{"content":"IDBots preference loop P1 Task 3 (commit fca4fed6, branch feat/preference-p1-engine): added src/main/services/preference/engine.ts — the pure deterministic Copeland tally per protocol 09-preference.md §5: compareOrderKey (height, txIndex, timestampMs, pinId), resolveRound, statusAt (collecting/revealing/settling + finality grace), and tallyRound (effective-commit selection with re-commit supersession, counted-reveal window checks, hash re-verification, conflict-of-interest pair exclusion §5.2, integer pair points §5.3, ranking by copeland/points/ref §5.4, judge agreement with leave-one-out Laplace BP §5.6, dimension aggregation §5.7, evidence = deciding+shadow reveal pins, tallyHash = sha256(canonJ(output)) with diagnostics never hashed §5.8). Tests: 19 hand-derived scenario vectors (basic winner, tie-breaks, conflict of interest, commit/reveal window violations, hash mismatch, recommit-latest-wins, invalid ballots, unconfirmed pins, public-never-decides, below minBallots, dimensions, agreement incl. A1 6000 / H1 6666 / H3 4000, status transitions) plus 3 invariance tests (hash stability under spam pins, input-order independence, invalid/unconfirmed round reporting) — 22/22 pass, compile:electron 0 errors, lint clean. Deviation: `!parsed.ok` narrowing rewritten as explicit `=== false/true` comparisons (project tsconfig is non-strict; semantics unchanged).","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}