Skip to content

Guard combat HP writes with character versions - #198

Merged
adrev merged 1 commit into
mainfrom
codex/combat-hp-version-authority
Aug 6, 2026
Merged

Guard combat HP writes with character versions#198
adrev merged 1 commit into
mainfrom
codex/combat-hp-version-authority

Conversation

@adrev

@adrev adrev commented Aug 6, 2026

Copy link
Copy Markdown
Owner

What changed

  • load the backing character version before damage, healing, or stabilization
  • guard every character HP/death-save write with that version and fail closed on conflicts
  • restore live combat state when a guarded write fails
  • defer condition mutations and broadcasts until the character write succeeds
  • await stabilization persistence and report the actual applied healing amount

Why

Combat HP actions previously wrote without an optimistic version condition. A simultaneous character-sheet edit could be overwritten, and failed writes could leave the live room state ahead of PostgreSQL.

Validation

  • npm test on Node 24: 145 files, 1,794 tests passed
  • npm run lint on Node 24
  • npm run build on Node 24
  • npm audit --audit-level=high: 0 vulnerabilities

Summary by CodeRabbit

  • Bug Fixes
    • Improved combat HP, damage, healing, and stabilization reliability by preventing stale updates from overwriting newer character data.
    • Invalid or unavailable character state is now rejected safely without changing combat state or sending misleading updates.
    • Failed HP changes restore temporary HP, death saves, conditions, and other in-memory combat details.
    • Wild Shape transitions now preserve character defenses and movement values when updates fail.
    • Healing and natural-20 death-save handling now remain consistent with saved character state.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0de666b5-c3f2-4c1f-a0a4-6907d9afc299

📥 Commits

Reviewing files that changed from the base of the PR and between aa4be2d and 65f33d3.

📒 Files selected for processing (7)
  • server/src/__tests__/character-version-propagation.test.ts
  • server/src/__tests__/chatCommands-tiers-10-20.test.ts
  • server/src/__tests__/chatCommands-tiers-21-25.test.ts
  • server/src/__tests__/combat-bugfixes.test.ts
  • server/src/__tests__/combat-hp-events.test.ts
  • server/src/__tests__/combat-live-stat-privacy.test.ts
  • server/src/services/CombatService.ts

📝 Walkthrough

Walkthrough

CombatService now validates authoritative character HP state and version data before damage, healing, and stabilization. Guarded writes reject stale or invalid updates, restore live combat state, and report errors. Tests update database mocks and cover conflicts, missing rows, and rollback behavior.

Changes

Combat HP concurrency protection

Layer / File(s) Summary
Authoritative character state loading
server/src/services/CombatService.ts
CombatService validates character rows, Wild Shape data, and versions before HP operations.
Guarded HP mutations
server/src/services/CombatService.ts
Damage, healing, and stabilization use version-guarded writes. Failed writes restore HP, temporary HP, death saves, and related state.
Concurrency and authority test coverage
server/src/__tests__/character-version-propagation.test.ts, server/src/__tests__/combat-bugfixes.test.ts, server/src/__tests__/combat-hp-events.test.ts, server/src/__tests__/combat-live-stat-privacy.test.ts, server/src/__tests__/chatCommands-tiers-10-20.test.ts, server/src/__tests__/chatCommands-tiers-21-25.test.ts
Tests mock authoritative reads and guarded updates. Coverage verifies fail-closed behavior, rollback, version conflicts, and death-save flows.

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

Sequence Diagram(s)

sequenceDiagram
  participant CombatService
  participant Database
  participant CombatState
  participant Session
  CombatService->>Database: Load authoritative character state and version
  Database-->>CombatService: Character row
  CombatService->>CombatState: Apply combat HP mutation
  CombatService->>Database: Persist HP with version guard
  alt Update succeeds
    Database-->>CombatService: Updated version
    CombatService->>Session: Emit combat update
  else Update fails
    Database-->>CombatService: Conflict or invalid result
    CombatService->>CombatState: Restore prior state
    CombatService->>Session: Send retry error
  end
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the pull request's main change: adding character-version guards to combat HP writes.
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
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/combat-hp-version-authority

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

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

@adrev
adrev marked this pull request as ready for review August 6, 2026 07:37
@adrev
adrev merged commit 3aeb82d into main Aug 6, 2026
1 of 2 checks passed
@adrev
adrev deleted the codex/combat-hp-version-authority branch August 6, 2026 07:42
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