Add ContractCompletionOperations orchestrator (deliver-then-mark,
outcome audit), hook from EncounterCompletionOperations after E5.M3
loot and quest wiring, extend dev fixture reset for contract rows,
Bruno quest-fixture reset request, and cover with tests (904 green).
Read the active index under the player lock and remove stale entries
only when the indexed instance id still matches, preventing concurrent
get/complete/reissue from dropping a newer active pointer.
Lock idempotency keys alongside row ids in TryAppend so concurrent
duplicate keys cannot both succeed; return true from TryClearInstance
when the row is absent to match Postgres idempotent DELETE behavior.
Nest player and instance locks in TryCreateActive, TryMarkComplete, and
TryClearInstance so concurrent create and complete cannot leave a stale
active index or mismatched snapshot.
Ensure instance schema before outcome DDL, require matching player/instance
on Postgres append, catch unique violations on concurrent duplicates, and
add parity plus concurrency integration tests.
Replace .ToArray() with collection spread, simplify single-statement
await using blocks, use Lock for Postgres schema gates, and document
IDE0063/IDE0305/IDE0330/CA1859 conventions in csharp-style.md.
Durable per-player contract instances (one active) and append-only
outcome audit rows, mirroring NEO-116/135 store patterns with V011/V012
migrations, AAA tests, README docs, and Bruno health smoke.
Primary constructor on ContractTemplateCatalog; concrete List return
types in loader parse helpers; collection spread in NormalizeBundle;
const emptyCatalog in roster gate test.
Startup loader mirrors validate_content.py E7M4 gates (roster, freeze,
cross-ref, band caps); IContractTemplateRegistry resolves templates by id.
Bruno health smoke confirms host boot after catalog validation.