The threading model's forbidden-patterns table bans new Thread,
ConcurrentQueue, Interlocked, Semaphore and volatile in UOContent, and its
exceptions list covered only Projects/Server. Both the new password
verification worker and the existing Advanced Search fan-out already sat
outside it, so the rule as written flagged working code.
Adds a vetted-workers section that leads with proving the need rather than
listing primitives: measure on-loop time rather than wall-clock, gate on core
count because off-loading creates no CPU, and account for what stays behind.
Game logic is still never threaded -- if it is too slow for one tick it gets
chunked across ticks, and that is spelled out with an example so the
distinction is not left implicit. Then the five rules a worker must satisfy,
and the hand-off protocol in both directions, including that the continuation
must re-validate anything that could have moved and that a failure must still
post a verdict.
Both vetted workers are listed with their justification, so a future reader
can tell whether either still earns its complexity.
CLAUDE.md rule #10 gains the same "prove it first" clause. Rules #3 and #10
already covered chunking, yielding to saves, and both hand-back routes.
Also trims the implementation comments: the measurement narrative belongs in
the handoff document, not in a class header.
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 :#