Agent skill
pm-validation-architecture
Detect and validate client-authoritative vs server-authoritative architecture gaps
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/pm-validation-architecture
SKILL.md
Architecture Validation Skill
"Server-authoritative code must have specific validation markers. If markers are missing, code is likely client-authoritative."
When to Use This Skill
Use during retrospective synthesis when analyzing why multiplayer features may not be truly server-authoritative.
Critical Detection Pattern
Retrospective 2026-01-22 Finding: Tasks marked serverAuthoritative: true had 100% client-side implementation.
Detection Pattern:
- Task marked as
serverAuthoritative: true - Code review shows client calculates state directly
- Server only logs input, doesn't process
- TODO comments exist in server code (e.g., "TODO: Forward to ECS")
Architecture Validation Checklist
For each task marked serverAuthoritative: true:
Step 1: Check Client Code
# Search for direct state manipulation (anti-pattern)
grep -r "velocity.x = " src/components/game/player/
grep -r "position.x += " src/components/game/player/
grep -r "rigidBody.setVelocity" src/components/game/
# These indicate CLIENT-SIDE physics (not server-authoritative)
What to look for:
| Pattern | Indicates | Correct Pattern |
|---|---|---|
rigidBody.setVelocity() |
Client-authoritative | networkManager.send({ type: 'input', ... }) |
position.x += input.x |
Client-authoritative | Server applies velocity |
if (hit) spawnDecal() |
Client-authoritative | Server confirms hit, then spawn |
score += 10 |
Client-authoritative | Server calculates score |
Step 2: Check Server Code
# Search for actual input processing (good pattern)
grep -A 10 "onMessage" server/rooms/GameRoom.ts
# Look for TODO comments (warning sign)
grep -r "TODO" server/rooms/GameRoom.ts
What to look for:
| Pattern | Indicates | Correct Pattern |
|---|---|---|
console.log(data) only |
Server not processing | Input validation + simulation |
TODO: Forward to ECS |
Incomplete implementation | ECS integration complete |
| Empty message handler | Server ignores client | Handler processes input |
Step 3: Check Message Flow
// CORRECT: Server-authoritative message flow
// Client (PlayerController.tsx)
networkManager.send({
type: 'player_input',
input: { forward, backward, left, right, jump },
sequence: inputSequence++
});
// Server (GameRoom.ts)
onMessage(client, data) {
if (data.type === 'player_input') {
const input = data.input;
// VALIDATE
if (!validateInput(input, player)) return;
// PROCESS
const velocity = calculateVelocity(input);
player.x += velocity.x * dt;
player.z += velocity.z * dt;
// BROADCAST
this.broadcast({
type: 'player_state',
sessionId: client.sessionId,
position: { x: player.x, z: player.z }
});
}
}
Detection: Code Review Commands
# Check if movement is client-authoritative
rg "rigidBody\.velocity|setVelocity|setLinvel" src/components/game/player/
# Check if shooting is client-authoritative
rg "spawnProjectile|createProjectile" src/components/game/weapons/
# Check for TODO comments indicating incomplete server implementation
rg "TODO.*server|TODO.*ECS" server/
Architecture Gap Detection Matrix
| Feature | Client Code | Server Code | Gap |
|---|---|---|---|
| Movement | PlayerController.tsx:520-678 (direct velocity) | GameRoom.ts:265-282 (log only) | ✗ Client-authoritative |
| Shooting | PaintGun.tsx:208-394 (spawn projectile) | GameRoom.ts:287-299 (broadcast only) | ✗ Client-authoritative |
| Score | HUD.tsx (local calculation) | No server score tracking | ✗ Client-authoritative |
PRD Update Pattern
When architecture gaps are detected, update PRD:
{
"id": "iter4-002",
"serverAuthoritative": false,
"revalidationRequired": true,
"notes": "CODE REVIEW 2026-01-22: Currently 100% client-side. Needs validate-001 to implement server-authoritative movement."
}
Create new validation tasks:
{
"id": "validate-001",
"title": "Server-Authoritative Movement Implementation",
"description": "Refactor movement to be server-authoritative...",
"acceptanceCriteria": [
"Client sends input state via NetworkManager (not velocity)",
"Server receives input messages in GameRoom",
"Server validates input (speed limits, jump cooldowns)",
"Server calculates velocity server-side",
"TODO at GameRoom.ts:273 resolved"
]
}
Red Flags for Client-Authoritative Code
| Symptom | Check | Result |
|---|---|---|
| TODO comments in GameRoom.ts | rg "TODO" server/rooms/GameRoom.ts |
Found: "TODO: Forward to player entity in ECS" |
| Direct physics manipulation on client | rg "setVelocity|velocity\.x\s*=" src/ |
Found: Client controls physics |
| No input validation on server | Check onMessage handlers |
Found: Only console.log |
| Server doesn't calculate state | Check server update loop | Found: MovementSystem.ts only syncs |
Validation Script
// scripts/validate-server-authoritative.ts
import { readFileSync } from 'fs';
import { globSync } from 'glob';
interface ValidationResult {
taskId: string;
feature: string;
clientAuthoritative: boolean;
issues: string[];
}
function validateServerAuthoritative(taskId: string): ValidationResult {
const issues: string[] = [];
let clientAuthoritative = false;
// Check client code for direct state manipulation
const clientFiles = globSync(`src/components/game/**/*.tsx`);
for (const file of clientFiles) {
const content = readFileSync(file, 'utf-8');
if (content.includes('rigidBody.setVelocity') ||
content.includes('velocity.x =') ||
content.includes('position.x +=')) {
issues.push(`${file}: Direct state manipulation detected`);
clientAuthoritative = true;
}
}
// Check server code for input processing
const serverFiles = globSync(`server/**/*.ts`);
for (const file of serverFiles) {
const content = readFileSync(file, 'utf-8');
if (content.includes('TODO')) {
issues.push(`${file}: TODO comment indicates incomplete implementation`);
clientAuthoritative = true;
}
if (content.includes('console.log') && !content.includes('validate')) {
issues.push(`${file}: Input logged but not validated`);
clientAuthoritative = true;
}
}
return {
taskId,
feature: taskId,
clientAuthoritative,
issues
};
}
Decision Framework
| Question | Yes → | No → |
|---|---|---|
| Client sends input (WASD, aim)? | Continue | ❌ Not server-authoritative |
| Server validates input? | Continue | ❌ Client-authoritative |
| Server calculates state? | Continue | ❌ Client-authoritative |
| Server broadcasts state? | Continue | ❌ Client-authoritative |
| Server rejects invalid input? | ✓ Server-authoritative | ⚠ Partial |
Retrospective Questions for Architecture Validation
During retrospective, ask Developer:
-
Does client send input or state?
- Input (WASD, aim) → ✓ Correct
- State (position, velocity) → ✗ Client-authoritative
-
Does server validate input?
- Yes (speed limits, cooldowns) → ✓ Correct
- No (accepts all input) → ✗ Not server-authoritative
-
Does server calculate game state?
- Yes (physics, collisions) → ✓ Correct
- No (client calculates) → ✗ Client-authoritative
-
Are there TODO comments in server code?
- Yes → ⚠ Incomplete implementation
- No → ✓ Likely complete
Anti-Patterns
❌ DON'T:
- Trust PRD
serverAuthoritative: truewithout code review - Assume server code processes input without checking
- Skip checking for TODO comments
- Ignore client-side direct state manipulation
✅ DO:
- Code review every
serverAuthoritative: truetask - Check client code for direct state changes
- Check server code for actual input processing
- Look for TODO comments as warning signs
- Create validation tasks when gaps found
Skill Improvement
After detecting architecture gaps:
- Update this skill with new detection patterns
- Add code examples from actual project
- Create validation tasks in PRD
- Update Developer skill with server-authoritative patterns
Reference
- dev-multiplayer-colyseus-server — Server-authoritative implementation
- pm-retrospective-facilitation — When to use this detection
- qa-multiplayer-testing — Testing server authority
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?