Every ModernUO shard has always run Argon2, so the RunUO/ServUO migration
shapes the repair path existed to recover do not occur in practice. It was
never free: it retried a failed verify against the other phrase rule, and
nothing in a stored hash separates a mis-migrated credential from a password
that merely begins with the username -- which is why it needed a per-account
tag on top of the config switch to be safe at all.
Removing it takes accountSecurity.repairMigratedPasswords, the RepairPasswordTag
opt-in and the forced rehash with it. The rehash on a successful login is now
implicit: stale algorithm or stale parameters, nothing else.
Also trims the development narrative out of the comments left behind.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add the new accountSecurity.* keys to the configuration.md examples
list, immediately after the accountHandler.* entries, matching the
key-naming convention already documented there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
- Adds CLAUDE.md at repo root with 14 terse code audit rules (always loaded, low token cost)
- Adds pointer files for other AI tools: AGENTS.md (Codex), GEMINI.md, .github/COPILOT-INSTRUCTIONS.md (Copilot), .cursorrules (Cursor) — all redirect to CLAUDE.md as single source of truth
- Gitignores /.claude so personal AI config isn't distributed
- Moves Claude skills to dev-docs/claude-skills/ (opt-in, not auto-loaded)
- Adds 14 dev-docs covering codebase conventions
Code Audit Rules (in CLAUDE.md)
1. LINQ tiered rules (Tier 1 free, Tier 2 warm, Tier 3 forbidden)
2. No Console.WriteLine — use LogFactory.GetLogger()
3. No concurrency primitives in game code
4. No World.Mobiles/World.Items iteration
5. Clean up refs in OnDelete()/OnAfterDelete()
6. Cancel timers in OnDelete()/OnAfterDelete()
7. STArrayPool<T>.Shared not ArrayPool<T>.Shared
8. PooledRefList<T> not new List<T>() on hot paths
9. Serialization: partial class, [Constructible], no serialized TimerExecutionToken
10. No Task.Run/new Thread() in game code
11. Never assume era — ask which expansion
12. _camelCase fields, PascalCase properties/methods
13. No empty gumps — use DisplayTo() pattern
14. PropertyList string literals must be {} holes, cliloc-as-argument uses :#