| 2026-06-12 14:59 | Keep unread notifications through presence leases | Michael Camilleri | 4 | +28 | -3 |
| 2026-06-12 14:07 | Truncate identifiers in the diagnostics log | Michael Camilleri | 3 | +137 | -1 |
| 2026-06-12 13:48 | Seed the share sheet's invite limit from the share | Michael Camilleri | 3 | +47 | -5 |
| 2026-06-12 13:23 | Settle public-link joins with a consumable seat ticket | Michael Camilleri | 2 | +127 | -12 |
| 2026-06-12 09:54 | Limit shared puzzles to one invitee | Michael Camilleri | 5 | +165 | -44 |
| 2026-06-12 09:23 | Add script to generate marketing image | Michael Camilleri | 5 | +349 | -60 |
| 2026-06-12 08:04 | Prevent animated transition when changing nicknames | Michael Camilleri | 1 | +1 | -2 |
| 2026-06-12 07:59 | Use nicknames in announcement banners | Michael Camilleri | 3 | +45 | -1 |
| 2026-06-12 07:41 | Support adding nicknames to friends | Michael Camilleri | 18 | +744 | -18 |
| 2026-06-12 03:18 | Log the worker's publish delivery counts in diagnostics | Michael Camilleri | 2 | +44 | -8 |
| 2026-06-12 02:41 | Reenable sound for session begin notifications | Michael Camilleri | 1 | +3 | -10 |
| 2026-06-12 02:38 | Add per-kind notification preferences | Michael Camilleri | 7 | +211 | -16 |
| 2026-06-12 01:46 | Add store-and-forward window for meaningful events | Michael Camilleri | 1 | +21 | -4 |
| 2026-06-12 01:26 | Add a Crossmates sheet for viewing and blocking friends | Michael Camilleri | 5 | +158 | -38 |
| 2026-06-12 00:44 | Register engagement room secrets instead of trusting first connect | Michael Camilleri | 5 | +239 | -42 |
| 2026-06-11 23:44 | Preserve the failing Core Data store before destructive recovery | Michael Camilleri | 3 | +135 | -7 |
| 2026-06-11 23:30 | Guard push secret generation and document the address capability boundary | Michael Camilleri | 2 | +20 | -5 |
| 2026-06-11 23:24 | Derive the APNs environment from a single build setting | Michael Camilleri | 5 | +28 | -7 |
| 2026-06-11 22:55 | Remove bearer token support from Cloudflare Worker | Michael Camilleri | 2 | +4 | -20 |
| 2026-06-11 20:44 | Remove diagnostic logging in Cloudflare Worker | Michael Camilleri | 1 | +0 | -205 |
| 2026-06-11 20:27 | Fix App Attest assertion verification in the push worker | Michael Camilleri | 2 | +410 | -53 |
| 2026-06-11 07:17 | Authenticate push worker requests with App Attest | Michael Camilleri | 8 | +944 | -43 |
| 2026-06-11 05:45 | Cap the Diagnostics event list at the last 50 entries | Michael Camilleri | 1 | +13 | -2 |
| 2026-06-11 05:40 | Mirror EventLog breadcrumbs into the unified system log | Michael Camilleri | 1 | +21 | -0 |
| 2026-06-11 05:39 | Skip session pushes to recipients leased into the game | Michael Camilleri | 3 | +93 | -13 |
| 2026-06-11 03:41 | Add profile name to Settings view | Michael Camilleri | 1 | +76 | -0 |
| 2026-06-11 02:52 | Sync display names as versioned 'name' Decisions in friend zones | Michael Camilleri | 15 | +809 | -252 |
| 2026-06-10 23:53 | Derive a completed game's thumbnail from the completion latch | Michael Camilleri | 3 | +116 | -4 |
| 2026-06-10 15:12 | Ignore unchanged self Player echoes and log read-cursor adoptions | Michael Camilleri | 3 | +33 | -6 |
| 2026-06-10 13:12 | Collapse session timers into a per-open-game PuzzleSession controller | Michael Camilleri | 7 | +620 | -265 |
| 2026-06-10 08:59 | Extract account push credentials and the replay cache from AppServices | Michael Camilleri | 6 | +440 | -350 |
| 2026-06-10 08:30 | Extract the invite/ping manager from AppServices | Michael Camilleri | 6 | +672 | -595 |
| 2026-06-10 08:11 | Split AppServices into composed session/engagement/badge services | Michael Camilleri | 9 | +1340 | -1137 |
| 2026-06-10 07:33 | Scope Moves enqueues to the current author's row | Michael Camilleri | 2 | +134 | -18 |
| 2026-06-10 04:07 | Fix incorrect comment | Michael Camilleri | 1 | +10 | -4 |
| 2026-06-10 04:05 | Trace inbound-apply save failures to the diagnostics log | Michael Camilleri | 2 | +61 | -32 |
| 2026-06-10 03:57 | Split the badge ledger's seen horizon from its suppression horizon | Michael Camilleri | 3 | +188 | -9 |
| 2026-06-10 02:58 | Split the read watermark from the presence lease | Michael Camilleri | 10 | +226 | -84 |
| 2026-06-09 19:09 | Stop draining CKSyncEngine on every live Moves edit | Michael Camilleri | 6 | +70 | -30 |
| 2026-06-09 18:02 | Remove replay tuning from Settings menu | Michael Camilleri | 2 | +7 | -76 |
| 2026-06-09 17:56 | Remove engagement menu option | Michael Camilleri | 4 | +5 | -42 |
| 2026-06-09 17:40 | Grace a lapsed read lease before treating a peer as gone | Michael Camilleri | 7 | +130 | -25 |
| 2026-06-09 16:11 | Reconcile badge ledger repeatedly | Michael Camilleri | 1 | +8 | -1 |
| 2026-06-09 14:18 | Stop forcing CloudKit drains on leave-path Player sends | Michael Camilleri | 5 | +62 | -36 |
| 2026-06-09 10:38 | Window session-end pushes on a per-peer notified-through mark | Michael Camilleri | 5 | +119 | -10 |
| 2026-06-09 02:07 | Persist the diagnostics event log across launches | Michael Camilleri | 2 | +97 | -5 |
| 2026-06-09 01:55 | Fix warning about unused variable | Michael Camilleri | 1 | +1 | -1 |
| 2026-06-09 01:44 | Reassert the active read lease after a sibling collapse | Michael Camilleri | 3 | +53 | -98 |
| 2026-06-09 00:31 | Recompute the read horizon from sibling leases | Michael Camilleri | 3 | +110 | -45 |
| 2026-06-08 23:18 | Refuse to collapse an active read lease from a sibling horizon | Michael Camilleri | 3 | +36 | -11 |
| 2026-06-08 22:49 | Converge the catch-up baseline regardless of cursor recency | Michael Camilleri | 2 | +106 | -11 |
| 2026-06-08 15:09 | Allow the account push secret to be rotated | Michael Camilleri | 6 | +313 | -62 |
| 2026-06-08 14:20 | Preserve unknown provider sessions | Michael Camilleri | 8 | +242 | -54 |
| 2026-06-08 13:32 | Sync the catch-up baseline across devices | Michael Camilleri | 10 | +259 | -73 |
| 2026-06-07 22:45 | Prune stale invite and badge rows | Michael Camilleri | 2 | +136 | -12 |
| 2026-06-07 21:42 | Consume declined invite Pings across devices | Michael Camilleri | 3 | +70 | -24 |
| 2026-06-07 10:53 | Use symbols rather than labels where possible | Michael Camilleri | 6 | +41 | -10 |
| 2026-06-07 10:23 | Tweak announcement wording | Michael Camilleri | 3 | +18 | -8 |
| 2026-06-07 09:29 | Refine NYT random puzzle selection | Michael Camilleri | 3 | +56 | -22 |
| 2026-06-07 07:31 | Bound archive replay retries to cold launch | Michael Camilleri | 3 | +50 | -12 |
| 2026-06-07 07:06 | Consume unactionable invite Pings before presentation | Michael Camilleri | 2 | +111 | -20 |
| 2026-06-07 06:36 | Tweak announcement formatting | Michael Camilleri | 2 | +4 | -4 |
| 2026-06-07 06:11 | Adjust font size in announcement banners | Michael Camilleri | 1 | +2 | -2 |
| 2026-06-07 05:53 | Restyle announcement banners | Michael Camilleri | 6 | +70 | -56 |
| 2026-06-07 04:54 | Add random puzzle button to provider's browse view | Michael Camilleri | 1 | +146 | -1 |
| 2026-06-07 00:47 | Rename field on Archive record type | Michael Camilleri | 1 | +2 | -2 |
| 2026-06-06 23:43 | Archive finished shared games to each player's private zone | Michael Camilleri | 9 | +1114 | -5 |
| 2026-06-06 17:27 | Delete the invite Ping when leaving a shared game | Michael Camilleri | 2 | +52 | -0 |
| 2026-06-06 15:44 | Hoist clue-at-position lookup onto Puzzle | Michael Camilleri | 3 | +12 | -18 |
| 2026-06-06 15:36 | Retain diagnostics events by time, not count | Michael Camilleri | 1 | +30 | -2 |
| 2026-06-06 15:23 | Move iPadOS's Clue List during replay | Michael Camilleri | 2 | +38 | -5 |
| 2026-06-06 14:15 | Add express gameID to Puzzle Grid | Michael Camilleri | 1 | +1 | -0 |
| 2026-06-06 14:10 | Add logging to app badging | Michael Camilleri | 2 | +18 | -0 |
| 2026-06-06 13:57 | Count pending invites toward the app-icon badge | Michael Camilleri | 8 | +151 | -11 |
| 2026-06-06 06:52 | Shrink the Puzzle Header at large Dynamic Type | Michael Camilleri | 1 | +18 | -1 |
| 2026-06-06 05:54 | Adjust placement of replay controls | Michael Camilleri | 1 | +6 | -2 |
| 2026-06-06 04:24 | Show replay progress in Success Panel | Michael Camilleri | 8 | +157 | -35 |
| 2026-06-06 03:45 | Add cache busting value for undo/redo | Michael Camilleri | 1 | +9 | -0 |
| 2026-06-06 03:37 | Fix header pinning incorrectly | Michael Camilleri | 1 | +1 | -1 |
| 2026-06-06 03:36 | Remove superfluous copy button | Michael Camilleri | 1 | +0 | -4 |
| 2026-06-06 02:37 | Bump maximum log entries to 1000 | Michael Camilleri | 1 | +1 | -1 |
| 2026-06-06 02:33 | Clarify replay playback controls | Michael Camilleri | 10 | +383 | -355 |
| 2026-06-06 01:55 | Support sharing of diagnostics via a text file | Michael Camilleri | 1 | +37 | -1 |
| 2026-06-06 01:45 | Widen scope where push notifications are in Notification Centre | Michael Camilleri | 1 | +2 | -2 |
| 2026-06-06 00:34 | Add logging for lease minting | Michael Camilleri | 1 | +10 | -0 |
| 2026-06-06 00:04 | Add logging for foreign Player writes | Michael Camilleri | 1 | +51 | -0 |
| 2026-06-05 21:47 | Render the local cursor behind the grid, not in every cell | Michael Camilleri | 2 | +97 | -52 |
| 2026-06-05 20:50 | Keep puzzle grid layers aligned on iPad | Michael Camilleri | 1 | +110 | -50 |
| 2026-06-05 13:39 | Add logging for badges on launch | Michael Camilleri | 1 | +65 | -0 |
| 2026-06-05 13:20 | Adopt a sibling's push secret before minting a competing one | Michael Camilleri | 1 | +28 | -0 |
| 2026-06-05 11:18 | Make account decision payloads durable and adopt on conflict | Michael Camilleri | 1 | +70 | -11 |
| 2026-06-05 10:31 | Derive per-game push addresses from one account secret | Michael Camilleri | 7 | +300 | -139 |
| 2026-06-05 07:36 | Unify completion detection into one provenance-tagged event | Michael Camilleri | 3 | +105 | -39 |
| 2026-06-05 06:05 | Log remote peer presence transitions | Michael Camilleri | 1 | +47 | -0 |
| 2026-06-05 05:20 | Treat pending private zones as freshen-ready | Michael Camilleri | 5 | +104 | -21 |
| 2026-06-05 05:19 | Rename directory to Workers | Michael Camilleri | 7 | +3 | -2 |
| 2026-06-05 03:27 | Update AGENTS.md | Michael Camilleri | 2 | +15 | -11 |
| 2026-06-04 23:20 | Show wrong-fill alert only for local attempts | Michael Camilleri | 3 | +45 | -15 |
| 2026-06-04 15:30 | Refresh the roster on new contributors only | Michael Camilleri | 5 | +164 | -23 |
| 2026-06-04 14:53 | Apply remote moves as a diff in GameStore.restore | Michael Camilleri | 1 | +31 | -6 |
| 2026-06-04 12:37 | Handle deleting games from the notification ledge | Michael Camilleri | 4 | +65 | -12 |
| 2026-06-04 06:33 | Seed Core Data unread values into the badge ledger for the NSE | Michael Camilleri | 5 | +79 | -9 |
| 2026-06-04 05:53 | Propagate seen horizons to sibling devices | Michael Camilleri | 1 | +27 | -5 |
| 2026-06-04 05:43 | Track badge unread state with horizons | Michael Camilleri | 4 | +121 | -52 |
| 2026-06-04 05:25 | Add account-level silent push routing | Michael Camilleri | 8 | +281 | -14 |
| 2026-06-03 23:04 | Tweak grace periods | Michael Camilleri | 1 | +2 | -2 |
| 2026-06-03 22:51 | Restore observed cell state when undoing local edits | Michael Camilleri | 4 | +95 | -5 |
| 2026-06-03 22:49 | Add logging for cookie errors | Michael Camilleri | 3 | +43 | -5 |
| 2026-06-03 06:36 | Nudge absent devices to upload replay journals | Michael Camilleri | 6 | +94 | -22 |
| 2026-06-03 05:09 | Lengthen the cursor debounce while a live room carries it | Michael Camilleri | 3 | +75 | -17 |
| 2026-06-03 04:41 | Add name to credits | Michael Camilleri | 1 | +12 | -0 |
| 2026-06-03 02:31 | Render peer cursor tints behind the grid, not in every cell | Michael Camilleri | 2 | +141 | -46 |
| 2026-06-02 20:32 | Collapse the cell-mark triple to a single markCode | Michael Camilleri | 24 | +317 | -256 |
| 2026-06-02 19:37 | Memoise the assembled replay timeline per game | Michael Camilleri | 4 | +131 | -21 |
| 2026-06-02 13:56 | Cache game replays in Core Data | Michael Camilleri | 7 | +308 | -30 |
| 2026-06-02 13:15 | Set a maximum width for scoreboard in Success Panel | Michael Camilleri | 1 | +5 | -1 |
| 2026-06-02 12:43 | Replay puzzles with a fast-forward control | Michael Camilleri | 4 | +212 | -5 |
| 2026-06-02 08:45 | Add version information to diagnostic logs | Michael Camilleri | 1 | +11 | -0 |
| 2026-06-02 08:02 | Summarise a paused session by gesture not touch | Michael Camilleri | 7 | +390 | -89 |
| 2026-06-02 05:14 | Extract ensureInBackground for guaranteed flushes | Michael Camilleri | 1 | +45 | -67 |
| 2026-06-02 05:02 | Keep a completed puzzle's authorship correct | Michael Camilleri | 5 | +78 | -14 |
| 2026-06-02 02:20 | Harden the engagement room and keep idle sockets warm | Michael Camilleri | 2 | +86 | -4 |
| 2026-06-02 01:54 | Gate the engagement socket on foreground | Michael Camilleri | 2 | +23 | -0 |
| 2026-06-01 22:36 | Add logging to push notifications | Michael Camilleri | 7 | +327 | -10 |
| 2026-06-01 15:37 | Fix Swift Concurrency warnings | Michael Camilleri | 4 | +4 | -5 |
| 2026-06-01 15:19 | Make a completed game terminal and read-only | Michael Camilleri | 6 | +275 | -7 |
| 2026-06-01 15:17 | Flush buffered cell edits under a background assertion | Michael Camilleri | 2 | +43 | -3 |
| 2026-06-01 08:06 | Reduce log noise regarding settled journals | Michael Camilleri | 1 | +8 | -0 |
| 2026-06-01 07:59 | Settle redundant journal uploads instead of retrying | Michael Camilleri | 1 | +29 | -3 |
| 2026-06-01 07:19 | Ensure a completed game's replay journal gets uploaded | Michael Camilleri | 4 | +127 | -20 |
| 2026-06-01 06:29 | Add logging to replay downloads | Michael Camilleri | 3 | +46 | -4 |
| 2026-06-01 05:54 | Coalesce a bulk gesture into one live update | Michael Camilleri | 4 | +194 | -69 |
| 2026-06-01 02:43 | Renew the read lease only while the app is foregrounded | Michael Camilleri | 2 | +76 | -7 |
| 2026-06-01 00:48 | Hold the replay scrubber's height while it loads | Michael Camilleri | 1 | +7 | -4 |
| 2026-05-31 23:13 | Tint the replay playhead with the acting author's colour | Michael Camilleri | 5 | +64 | -14 |
| 2026-05-31 23:11 | Retire the live session when a puzzle is completed | Michael Camilleri | 5 | +29 | -1 |
| 2026-05-31 14:38 | Add replay support to Success Panels | Michael Camilleri | 14 | +707 | -31 |
| 2026-05-31 05:07 | Carry session-push semantics in an opaque payload | Michael Camilleri | 10 | +466 | -43 |
| 2026-05-31 00:02 | Restore the typing direction when undoing a letter | Michael Camilleri | 7 | +126 | -35 |
| 2026-05-30 21:40 | Defer the session-begin push behind a grace window | Michael Camilleri | 2 | +61 | -10 |
| 2026-05-30 21:20 | Build the cross-device replay data layer | Michael Camilleri | 9 | +459 | -7 |
| 2026-05-30 20:03 | Gate the peer cursor and engagement teardown on the readAt lease | Michael Camilleri | 4 | +256 | -97 |
| 2026-05-30 14:39 | Stop the engagement backstop from re-leasing readAt in the background | Michael Camilleri | 2 | +12 | -2 |
| 2026-05-30 12:35 | Give MovesUpdater's flush context a merge policy | Michael Camilleri | 1 | +8 | -0 |
| 2026-05-30 12:28 | Stop dropping move-journal entries on Core Data merge conflicts | Michael Camilleri | 4 | +18 | -6 |
| 2026-05-30 06:27 | Follow the cursor on undo and redo | Michael Camilleri | 5 | +71 | -27 |
| 2026-05-30 04:46 | Wire up undo/redo controls in the puzzle grid | Michael Camilleri | 3 | +68 | -16 |
| 2026-05-30 01:57 | Upload move journal at game completion | Michael Camilleri | 8 | +554 | -1 |
| 2026-05-29 23:54 | Fix direct fetches dropping collaboration fields | Michael Camilleri | 2 | +32 | -8 |
| 2026-05-29 22:12 | Add move journal with undo/redo | Michael Camilleri | 9 | +877 | -51 |
| 2026-05-29 12:22 | Group revoked games into their own list section | Michael Camilleri | 2 | +45 | -2 |
| 2026-05-29 12:14 | Increase spacing in date picker | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-29 11:32 | Tighten debouncing gating | Michael Camilleri | 1 | +12 | -0 |
| 2026-05-29 11:04 | Change label for manual engagements | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-29 07:42 | Add remote-only active-puzzle debounce | Michael Camilleri | 1 | +35 | -1 |
| 2026-05-29 07:19 | Coalesce overlapping game-list refreshes | Michael Camilleri | 1 | +25 | -0 |
| 2026-05-29 07:06 | Log visible push notifications | Michael Camilleri | 4 | +105 | -0 |
| 2026-05-29 06:56 | Reduce CloudKit polling after fetch fan-out changes | Michael Camilleri | 2 | +126 | -57 |
| 2026-05-29 06:32 | Reduce CloudKit fetch fan-out during collaboration | Michael Camilleri | 5 | +129 | -161 |
| 2026-05-29 04:46 | Rendezvous live-engagement rooms on the Game record | Michael Camilleri | 8 | +271 | -477 |
| 2026-05-29 03:26 | Harden live-engagement reconnection | Michael Camilleri | 5 | +172 | -23 |
| 2026-05-29 02:00 | Improve success likelihood of session-end push | Michael Camilleri | 1 | +47 | -2 |
| 2026-05-29 01:24 | Address push notifications by capability token | Michael Camilleri | 12 | +429 | -80 |
| 2026-05-28 23:03 | Navigate to puzzle after creation | Michael Camilleri | 2 | +6 | -2 |
| 2026-05-28 22:29 | Load Schrödinger puzzles as rebuses | Michael Camilleri | 2 | +125 | -8 |
| 2026-05-28 14:00 | Rearchitect session summary push notifications | Michael Camilleri | 10 | +382 | -349 |
| 2026-05-28 05:33 | Update app badge from Notification Service Extension | Michael Camilleri | 11 | +406 | -26 |
| 2026-05-28 04:27 | Navigate to game on push notification tap | Michael Camilleri | 4 | +9 | -135 |
| 2026-05-28 03:06 | Refresh peer baselines on sibling readAt sync | Michael Camilleri | 3 | +98 | -1 |
| 2026-05-28 02:44 | Share session snapshot across an author's devices | Michael Camilleri | 11 | +337 | -98 |
| 2026-05-28 01:02 | Stop tracking local build server config | Michael Camilleri | 2 | +1 | -20 |
| 2026-05-27 22:52 | Use session-activity calculations consistently | Michael Camilleri | 11 | +697 | -713 |
| 2026-05-27 06:37 | Use private struct rather than long tuple for return value | Michael Camilleri | 2 | +66 | -67 |
| 2026-05-27 06:27 | Wake engagement on existing player presence updates | Michael Camilleri | 5 | +221 | -9 |
| 2026-05-27 05:29 | Consume stale .invite Pings before presenting them | Michael Camilleri | 1 | +58 | -15 |
| 2026-05-27 05:13 | Suppress play/pause pushes for finished or revoked games | Michael Camilleri | 3 | +77 | -20 |
| 2026-05-27 04:44 | Stamp completion from observed solved state | Michael Camilleri | 3 | +74 | -11 |
| 2026-05-27 03:37 | Send play/pause notifications more judiciously | Michael Camilleri | 2 | +62 | -7 |
| 2026-05-27 03:12 | Update .gitignore | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-27 02:43 | Address concurrency false positive | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-27 02:41 | Add push notification logging | Michael Camilleri | 2 | +44 | -14 |
| 2026-05-27 01:43 | Suppress stale peer cursor presence | Michael Camilleri | 3 | +52 | -17 |
| 2026-05-27 00:51 | Drain retired play-event pings and rename play/pause push kinds | Michael Camilleri | 4 | +81 | -9 |
| 2026-05-27 00:38 | Move user-facing notifications to APNs via a Cloudflare Worker | Michael Camilleri | 42 | +951 | -833 |
| 2026-05-26 21:53 | Make worker configuration explicit | Michael Camilleri | 2 | +7 | -0 |
| 2026-05-26 09:31 | Simplify sync design | Michael Camilleri | 5 | +47 | -251 |
| 2026-05-25 21:48 | Tweak colours of announcement icons | Michael Camilleri | 1 | +9 | -6 |
| 2026-05-25 17:44 | Deduplicate ping handling before dispatch | Michael Camilleri | 9 | +31 | -318 |
| 2026-05-25 17:24 | Disable polling while engagement is live | Michael Camilleri | 1 | +6 | -2 |
| 2026-05-25 17:12 | Stabilize socket engagements | Michael Camilleri | 5 | +83 | -18 |
| 2026-05-25 16:50 | Ensure protocol in URLs is wss | Michael Camilleri | 2 | +34 | -3 |
| 2026-05-25 16:39 | Remove excessive logging | Michael Camilleri | 1 | +0 | -6 |
| 2026-05-25 16:21 | Replace WebRTC engagements with socket rooms | Michael Camilleri | 16 | +696 | -1837 |
| 2026-05-25 15:00 | Add lag measuring instrumentation | Michael Camilleri | 1 | +9 | -4 |
| 2026-05-25 14:38 | Add further instrumentation to WebRTC bridge | Michael Camilleri | 1 | +99 | -0 |
| 2026-05-25 14:27 | Force engagements to use TURN server | Michael Camilleri | 1 | +27 | -1 |
| 2026-05-25 14:07 | Add additional instrumentation to WebRTC bridge | Michael Camilleri | 1 | +35 | -2 |
| 2026-05-25 13:48 | Keep engagement connections alive briefly after grid exit | Michael Camilleri | 6 | +73 | -6 |
| 2026-05-25 13:21 | Update Cloudflare app name | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-25 13:00 | Update .gitignore | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-25 12:54 | Add Cloudflare TURN credentials for engagements | Michael Camilleri | 9 | +233 | -20 |
| 2026-05-25 10:57 | Make engagement channel delivery reliable | Michael Camilleri | 3 | +18 | -4 |
| 2026-05-25 10:19 | Use cursor tracks for engagement presence | Michael Camilleri | 2 | +127 | -26 |
| 2026-05-25 09:56 | Fix manual engagement offers targeting self | Michael Camilleri | 2 | +34 | -3 |
| 2026-05-25 09:24 | Defer engagement .live promotion until the channel opens | Michael Camilleri | 2 | +120 | -16 |
| 2026-05-25 07:43 | Browse zones and records from Record Editor | Michael Camilleri | 2 | +201 | -0 |
| 2026-05-25 07:21 | Handle stuck engagement handshakes | Michael Camilleri | 2 | +227 | -10 |
| 2026-05-25 07:04 | Add WebRTC engagement bridge for co-solving engagements | Michael Camilleri | 24 | +2882 | -34 |
| 2026-05-24 21:12 | Wrap puzzle teardown in a Player send burst | Michael Camilleri | 1 | +9 | -0 |
| 2026-05-24 20:58 | Avoid peer presence pre-empting selection debounce | Michael Camilleri | 2 | +35 | -1 |
| 2026-05-24 20:48 | Gate cursor-track sends on peer presence | Michael Camilleri | 5 | +198 | -6 |
| 2026-05-24 09:02 | Tweak icons used in announcements | Michael Camilleri | 1 | +3 | -3 |
| 2026-05-24 05:39 | Add confirmation dialog when revealing | Michael Camilleri | 1 | +56 | -3 |
| 2026-05-24 04:15 | Replace Player coalesce timer with an explicit open burst | Michael Camilleri | 8 | +105 | -57 |
| 2026-05-24 00:41 | Select external provider if already enabled | Michael Camilleri | 1 | +5 | -0 |
| 2026-05-23 22:16 | Change symbol for info announcements | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-23 22:14 | Tweak time for coalescing | Michael Camilleri | 1 | +7 | -4 |
| 2026-05-23 21:53 | Coalesce Player-record sends and log send success correctly | Michael Camilleri | 6 | +105 | -16 |
| 2026-05-23 21:06 | Improve sophistication of try handling | Michael Camilleri | 9 | +214 | -68 |
| 2026-05-23 19:16 | Surface Core Data save failures in the diagnostics log | Michael Camilleri | 6 | +97 | -25 |
| 2026-05-23 19:14 | Set up xcode-build-server | Michael Camilleri | 2 | +24 | -0 |
| 2026-05-23 18:13 | Use 'Diagnostics Log' for name of log view | Michael Camilleri | 3 | +3 | -87 |
| 2026-05-23 10:10 | Use correct time when refetching puzzle | Michael Camilleri | 1 | +10 | -1 |
| 2026-05-23 09:12 | Increase diagnostic detail | Michael Camilleri | 2 | +27 | -9 |
| 2026-05-23 08:49 | Surface NYT upgrade outcome in the diagnostics log | Michael Camilleri | 5 | +58 | -24 |
| 2026-05-23 08:12 | Restore retry on failed NYT puzzle upgrades | Michael Camilleri | 3 | +2 | -4 |
| 2026-05-23 07:10 | Isolate NotificationState's UserDefaults per test | Michael Camilleri | 5 | +68 | -4 |
| 2026-05-23 06:57 | Support refreshing puzzles from external providers | Michael Camilleri | 11 | +397 | -3 |
| 2026-05-22 21:45 | Lay out the game list as a card grid on iPad | Michael Camilleri | 1 | +373 | -55 |
| 2026-05-22 13:09 | Withdraw a game's notifications when a sibling device opens it | Michael Camilleri | 1 | +11 | -2 |
| 2026-05-22 08:12 | Tweak colour of info announcements | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-22 06:27 | Tweak animations to make sending more obvious | Michael Camilleri | 1 | +85 | -9 |
| 2026-05-22 03:13 | Preview bundled puzzles in the puzzle picker | Michael Camilleri | 25 | +616 | -136 |
| 2026-05-21 23:28 | Browse bundled puzzles by named bundle | Michael Camilleri | 26 | +1194 | -1104 |
| 2026-05-21 23:20 | Delimit Fillmake's XD sections with two blank lines | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-21 16:44 | Add icons to announcement banners | Michael Camilleri | 1 | +43 | -17 |
| 2026-05-21 15:20 | Use player colour for info announcements | Michael Camilleri | 1 | +4 | -1 |
| 2026-05-21 14:36 | Drop a pending invite when its game's zone syncs in | Michael Camilleri | 2 | +42 | -3 |
| 2026-05-21 13:40 | Accept the CKShare when joining from an invite notification | Michael Camilleri | 2 | +62 | -9 |
| 2026-05-21 13:17 | Show banners when a puzzle's game is revoked or removed | Michael Camilleri | 7 | +138 | -7 |
| 2026-05-21 07:56 | Store session notification dedup per key | Michael Camilleri | 1 | +56 | -15 |
| 2026-05-21 07:23 | Thread tint colour consistently to SwiftUI views | Michael Camilleri | 3 | +11 | -6 |
| 2026-05-21 05:24 | Tweak Clue Bar background colour | Michael Camilleri | 3 | +8 | -3 |
| 2026-05-21 05:07 | Move session notification policy into SessionMonitor | Michael Camilleri | 5 | +184 | -91 |
| 2026-05-21 04:35 | Use consistent puzzle title | Michael Camilleri | 2 | +43 | -1 |
| 2026-05-21 04:35 | Support mockable sleep function in AnnouncementCenter | Michael Camilleri | 3 | +50 | -10 |
| 2026-05-21 03:47 | Improve NYT date navigation | Michael Camilleri | 1 | +57 | -1 |
| 2026-05-21 03:24 | Tweak colour tints | Michael Camilleri | 1 | +2 | -3 |
| 2026-05-21 03:04 | Block input on access-revoked puzzles via the announcement banner | Michael Camilleri | 4 | +48 | -35 |
| 2026-05-21 02:53 | Promote correct draft entries when checking | Michael Camilleri | 2 | +14 | -2 |
| 2026-05-21 02:51 | Prevent solved puzzle opens from sending win pings | Michael Camilleri | 1 | +33 | -20 |
| 2026-05-21 01:41 | Move the invite-accept error onto the announcement banner | Michael Camilleri | 1 | +26 | -14 |
| 2026-05-21 00:53 | Add in-puzzle announcement banner for session-end summaries | Michael Camilleri | 10 | +571 | -7 |
| 2026-05-20 23:29 | Notify when a collaborator's play session ends | Michael Camilleri | 11 | +1032 | -45 |
| 2026-05-20 21:21 | Avoid republishing unchanged roster entries | Michael Camilleri | 1 | +5 | -2 |
| 2026-05-20 12:38 | Remove numbers from all grid cells | Michael Camilleri | 2 | +2 | -43 |
| 2026-05-20 10:55 | Tidy sync engine support code | Michael Camilleri | 9 | +1777 | -1747 |
| 2026-05-20 10:21 | Add directive to use xcodegen to AGENTS.md | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-20 09:47 | Adjust display of text in grid cells | Michael Camilleri | 2 | +91 | -42 |
| 2026-05-20 06:06 | Direct and consume invite pings | Michael Camilleri | 5 | +170 | -12 |
| 2026-05-20 05:45 | Deduplicate cursor track publishing | Michael Camilleri | 3 | +18 | -16 |
| 2026-05-20 05:38 | Detach CKSyncEngine send drains from enqueue paths | Michael Camilleri | 1 | +20 | -13 |
| 2026-05-20 04:30 | Change merge policy to avoid loading failure errors | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-20 04:25 | Improve diagnostic information | Michael Camilleri | 1 | +43 | -3 |
| 2026-05-20 04:00 | Use lease-based suppression strategy while a puzzle is open | Michael Camilleri | 6 | +177 | -60 |
| 2026-05-20 02:09 | Fetch readAt field in direct sync paths | Michael Camilleri | 2 | +9 | -4 |
| 2026-05-20 00:11 | Replace .opened/.closed lease pings with Player.readAt | Michael Camilleri | 15 | +594 | -1000 |
| 2026-05-19 22:55 | Support seenOtherAt cursor on the Player record | Michael Camilleri | 2 | +53 | -0 |
| 2026-05-19 18:17 | Disable Release linker code-folding so crash frames symbolicate | Michael Camilleri | 2 | +14 | -5 |
| 2026-05-19 18:16 | Detach CKSyncEngine re-entry out of the onPings delegate callback | Michael Camilleri | 2 | +17 | -5 |
| 2026-05-19 11:55 | Fan out a directed .resign when resigning from the library | Michael Camilleri | 3 | +9 | -0 |
| 2026-05-19 11:37 | Replace the eternal win ping with directed, self-cleaning pings | Michael Camilleri | 5 | +222 | -102 |
| 2026-05-19 10:48 | Replace the broadcast win ping with directed completion pings | Michael Camilleri | 7 | +92 | -17 |
| 2026-05-19 07:02 | Wait for an invited game to sync before erroring | Michael Camilleri | 3 | +131 | -20 |
| 2026-05-19 06:44 | Add revision number and bundle identifier to template | Michael Camilleri | 1 | +2 | -0 |
| 2026-05-19 02:43 | Attempt to constrain height of scoreboard | Michael Camilleri | 1 | +2 | -0 |
| 2026-05-19 02:23 | Stick Puzzle Grid scoreboard to bottom of header | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-19 02:10 | Add Cluemake for generated crossword clues | Michael Camilleri | 4 | +596 | -7 |
| 2026-05-19 01:38 | Use invitation animations in short list as well | Michael Camilleri | 1 | +17 | -18 |
| 2026-05-19 01:31 | Title the header scoreboard instead of centring it | Michael Camilleri | 1 | +11 | -7 |
| 2026-05-19 00:39 | Clean .puz author strings and label the credits page | Michael Camilleri | 1 | +16 | -1 |
| 2026-05-19 00:37 | Wrap and centre the header scoreboard chips | Michael Camilleri | 1 | +86 | -10 |
| 2026-05-18 22:15 | Add bundle-puzzles.sh to renumber picks into the app bundle | Michael Camilleri | 1 | +47 | -0 |
| 2026-05-18 22:11 | Update select_puzzles.sh to copy a ranked puzzle batch | Michael Camilleri | 2 | +59 | -13 |
| 2026-05-18 20:49 | Rebuild puzzle generation around Fillmake, Gridmake and Pickmake | Michael Camilleri | 11 | +2544 | -737 |
| 2026-05-18 20:25 | Add swipeable title/scoreboard/credits to Puzzle Grid | Michael Camilleri | 2 | +177 | -2 |
| 2026-05-18 10:55 | Animate the friend's own glyph as invite feedback | Michael Camilleri | 2 | +47 | -12 |
| 2026-05-18 04:20 | Spread the player palette and keep collaborators off similar hues | Michael Camilleri | 1 | +63 | -19 |
| 2026-05-18 00:16 | Propagate shared game departure to the user's own devices | Michael Camilleri | 4 | +160 | -7 |
| 2026-05-17 23:31 | Add high-level architecture description to AGENTS.md | Michael Camilleri | 1 | +12 | -0 |
| 2026-05-17 23:24 | Tweak pattern opacity | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-17 23:03 | Fix ping bugs | Michael Camilleri | 5 | +129 | -23 |
| 2026-05-17 22:10 | Sync the active-puzzle lease across a user's own devices | Michael Camilleri | 9 | +412 | -58 |
| 2026-05-17 15:33 | Hold a just-left puzzle active through a short grace window | Michael Camilleri | 3 | +90 | -10 |
| 2026-05-17 13:34 | Phase cross-reference hatching onto a grid-wide lattice | Michael Camilleri | 2 | +73 | -14 |
| 2026-05-17 13:15 | Make friend colours stable across games | Michael Camilleri | 9 | +69 | -458 |
| 2026-05-17 12:53 | Share the clue cell-walk behind a built-once start index | Michael Camilleri | 2 | +74 | -42 |
| 2026-05-17 12:32 | Mark cross-referenced squares with a passive pattern | Michael Camilleri | 3 | +166 | -1 |
| 2026-05-17 10:52 | Exclude completed puzzles from the ping fast path | Michael Camilleri | 1 | +27 | -2 |
| 2026-05-17 09:51 | Keep the ping fast-path from matching its own newest record | Michael Camilleri | 1 | +38 | -3 |
| 2026-05-17 08:56 | Fix misleading zone count | Michael Camilleri | 1 | +8 | -1 |
| 2026-05-17 07:35 | Reap pending sends that can no longer be built | Michael Camilleri | 3 | +135 | -2 |
| 2026-05-17 07:10 | Trace the ping send path in enqueuePing | Michael Camilleri | 1 | +29 | -2 |
| 2026-05-17 04:57 | Reap stale .opened pings from the account zone | Michael Camilleri | 3 | +129 | -1 |
| 2026-05-17 03:44 | Update script to archive into the Xcode library | Michael Camilleri | 1 | +11 | -2 |
| 2026-05-17 03:27 | Stop awaiting CKSyncEngine from inside delegate callback | Michael Camilleri | 1 | +12 | -3 |
| 2026-05-17 00:00 | Keep the clue list pinned to the current clue across foregrounding | Michael Camilleri | 1 | +9 | -0 |
| 2026-05-16 23:58 | Add build script | Michael Camilleri | 4 | +46 | -21 |
| 2026-05-16 21:05 | Fix test helper for debounce-coalesce tests | Michael Camilleri | 1 | +14 | -0 |
| 2026-05-16 20:48 | Improve friend-related features on multiple devices | Michael Camilleri | 4 | +333 | -11 |
| 2026-05-16 13:53 | Preview friend invites in the share sheet | Michael Camilleri | 4 | +182 | -22 |
| 2026-05-16 08:48 | Tighten friend invite acceptance and names | Michael Camilleri | 3 | +57 | -12 |
| 2026-05-16 07:56 | Add friend invites for past collaborators | Michael Camilleri | 18 | +1529 | -30 |
| 2026-05-15 21:45 | Persist the local cursor per game | Michael Camilleri | 6 | +294 | -19 |
| 2026-05-15 21:18 | Keep buffered letters from reverting on remote refresh | Michael Camilleri | 6 | +301 | -3 |
| 2026-05-15 11:12 | Represent XD specials with grid symbols | Michael Camilleri | 22 | +529 | -149 |
| 2026-05-15 09:12 | Show seven completed puzzles on launch | Michael Camilleri | 1 | +55 | -24 |
| 2026-05-15 08:45 | Use selection fill for remote Cursor Track | Michael Camilleri | 2 | +9 | -77 |
| 2026-05-15 07:48 | Dismiss notifications across user's devices | Michael Camilleri | 6 | +233 | -19 |
| 2026-05-15 07:43 | Gate lastSeenOtherMoveAt advance on puzzle visibility | Michael Camilleri | 2 | +72 | -0 |
| 2026-05-15 06:09 | Dismiss notifications when entering relevant game | Michael Camilleri | 2 | +22 | -0 |
| 2026-05-15 05:41 | Suppress redundant freshens between push signals | Michael Camilleri | 2 | +79 | -3 |
| 2026-05-15 02:59 | Preserve in-flight Game record against clobbering | Michael Camilleri | 6 | +80 | -8 |
| 2026-05-15 01:58 | Synchronise on state instead of wall-clock in mutator/clear tests | Michael Camilleri | 3 | +36 | -11 |
| 2026-05-14 19:22 | Expand usage of injectable debounce timing | Michael Camilleri | 4 | +61 | -35 |
| 2026-05-14 19:19 | Improve notifications | Michael Camilleri | 3 | +41 | -1 |
| 2026-05-14 18:36 | Show updated-game count on the app icon | Michael Camilleri | 4 | +84 | -5 |
| 2026-05-14 18:16 | Freshen the puzzle grid as its own sync surface | Michael Camilleri | 4 | +90 | -39 |
| 2026-05-14 16:00 | Add border to Cursor Track | Michael Camilleri | 2 | +69 | -11 |
| 2026-05-14 08:02 | Persist Cursor Track instead of Cursor Reticle | Michael Camilleri | 9 | +73 | -34 |
| 2026-05-14 06:39 | Coalesce Game List freshness checks | Michael Camilleri | 2 | +78 | -10 |
| 2026-05-14 06:06 | Freshen the game list as its own sync surface | Michael Camilleri | 3 | +111 | -10 |
| 2026-05-14 05:40 | Coalesce duplicate remote notification handlers | Michael Camilleri | 1 | +58 | -0 |
| 2026-05-14 05:35 | Avoid updated timestamps in Game records being overwritten with earlier timestamps | Michael Camilleri | 2 | +38 | -3 |
| 2026-05-14 05:24 | Catch up Game/Moves after background pushes | Michael Camilleri | 2 | +210 | -0 |
| 2026-05-14 05:05 | Refresh viewContext after MovesUpdater flush | Michael Camilleri | 1 | +24 | -1 |
| 2026-05-14 04:41 | Cut redundant CloudKit work | Michael Camilleri | 5 | +78 | -46 |
| 2026-05-14 04:07 | Trace PlayerRoster only after the post-fetch publish | Michael Camilleri | 1 | +31 | -15 |
| 2026-05-14 03:35 | Orphan shared zones whose participant binding turns invalid | Michael Camilleri | 1 | +56 | -12 |
| 2026-05-14 03:21 | Clear last sync error when its phase succeeds again | Michael Camilleri | 1 | +7 | -0 |
| 2026-05-14 03:20 | Drop fetched record snapshots older than local cache | Michael Camilleri | 2 | +58 | -8 |
| 2026-05-14 02:28 | Skip grid refresh when Moves save self-echoes | Michael Camilleri | 2 | +11 | -7 |
| 2026-05-14 02:00 | Use live fetches for open synced puzzles | Michael Camilleri | 3 | +45 | -30 |
| 2026-05-14 01:21 | Scope player name publish to open game | Michael Camilleri | 5 | +184 | -29 |
| 2026-05-13 23:58 | Clarify timezone in copied log lines | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-13 23:24 | Display log events in-app using local time | Michael Camilleri | 1 | +35 | -20 |
| 2026-05-13 23:06 | Use UTC when logging | Michael Camilleri | 1 | +3 | -1 |
| 2026-05-13 22:55 | Update length of log history | Michael Camilleri | 2 | +2 | -1 |
| 2026-05-13 22:47 | Add upload-only script | Michael Camilleri | 2 | +43 | -2 |
| 2026-05-13 21:49 | Infer session notifications from Player records | Michael Camilleri | 9 | +322 | -99 |
| 2026-05-12 20:31 | Skip the cell-cache rewrite when refreshing the current game | Michael Camilleri | 1 | +10 | -3 |
| 2026-05-12 20:09 | Make MovesUpdater debounce timing test-injectable | Michael Camilleri | 2 | +51 | -6 |
| 2026-05-12 20:08 | Parallelise refreshLibrary across database scopes | Michael Camilleri | 1 | +16 | -12 |
| 2026-05-12 19:48 | Parallelise discoverNewZonesDirect across zones and record types | Michael Camilleri | 1 | +62 | -33 |
| 2026-05-12 19:44 | Parallelise fetchPushPingsDirect across zones | Michael Camilleri | 1 | +39 | -17 |
| 2026-05-12 19:42 | Lower MovesUpdater debounce from 1500ms to 500ms | Michael Camilleri | 2 | +2 | -2 |
| 2026-05-12 19:29 | Kick sendChanges() on player, game and delete enqueues | Michael Camilleri | 1 | +3 | -0 |
| 2026-05-12 19:24 | Parallelise the silent-push handler and skip wasteful zone discovery | Michael Camilleri | 1 | +34 | -35 |
| 2026-05-12 10:16 | Increase timeout for flakey test | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-12 10:11 | Parallelise the library refresh and skip completed games | Michael Camilleri | 1 | +56 | -27 |
| 2026-05-12 09:10 | Pull updates for known game zones on library refresh | Michael Camilleri | 2 | +77 | -0 |
| 2026-05-12 08:40 | Discover unseen game zones without waiting on CKSyncEngine | Michael Camilleri | 4 | +164 | -22 |
| 2026-05-12 08:07 | Bump Crossmate-flavoured XD version | Michael Camilleri | 14 | +31 | -14 |
| 2026-05-12 08:04 | Render circled cells in converted puzzles | Michael Camilleri | 2 | +40 | -27 |
| 2026-05-12 07:19 | Surface collaborator pings on background push wakes | Michael Camilleri | 4 | +167 | -0 |
| 2026-05-11 22:23 | Tweak Clue Bar layout | Michael Camilleri | 1 | +5 | -4 |
| 2026-05-10 18:55 | Add Crossmate version to puzzle data structures | Michael Camilleri | 26 | +187 | -19 |
| 2026-05-10 18:30 | Update .gitignore | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-10 16:42 | Use publisher as a consistent name | Michael Camilleri | 14 | +768 | -768 |
| 2026-05-10 16:18 | Fix movement when deleting first letter of a word | Michael Camilleri | 2 | +85 | -3 |
| 2026-05-10 16:13 | Fix movement when typing last letter in a direction | Michael Camilleri | 3 | +109 | -10 |
| 2026-05-10 15:55 | Adjust touch target for previous/next buttons in Clue Bar | Michael Camilleri | 1 | +5 | -4 |
| 2026-05-10 15:25 | Improve latency of pings | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-10 14:17 | Clean up completed game ping records | Michael Camilleri | 3 | +93 | -1 |
| 2026-05-10 13:55 | Tweak layout of Clue List on iOS | Michael Camilleri | 1 | +25 | -11 |
| 2026-05-10 11:01 | Move diagnostics menu option into Puzzle Menu | Michael Camilleri | 1 | +10 | -15 |
| 2026-05-10 10:49 | Make diagnostics accessible from Puzzle View | Michael Camilleri | 1 | +16 | -0 |
| 2026-05-10 10:23 | Simplify push notification fallback | Michael Camilleri | 1 | +2 | -8 |
| 2026-05-10 06:18 | Limit push fallback to active game | Michael Camilleri | 2 | +139 | -89 |
| 2026-05-10 05:51 | Include Player records in fallback fetch | Michael Camilleri | 1 | +6 | -1 |
| 2026-05-09 05:09 | Disable solved puzzle toolbar actions | Michael Camilleri | 1 | +10 | -2 |
| 2026-05-09 03:01 | Load puzzles before roster refresh | Michael Camilleri | 5 | +93 | -50 |
| 2026-05-09 02:40 | Retry pending move flushes until persisted | Michael Camilleri | 3 | +35 | -15 |
| 2026-05-09 01:28 | Fix notification replay bug | Michael Camilleri | 3 | +12 | -20 |
| 2026-05-09 00:19 | Preserve local Moves record at all times | Michael Camilleri | 4 | +166 | -3 |
| 2026-05-08 22:40 | Fix Success Panel animation | Michael Camilleri | 1 | +23 | -9 |
| 2026-05-08 22:17 | Improve Success Panel animation | Michael Camilleri | 1 | +30 | -23 |
| 2026-05-08 21:14 | Extend divider into safe area in landscape | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-08 15:00 | Disable author tinting for local games | Michael Camilleri | 2 | +11 | -12 |
| 2026-05-08 14:39 | Collapse roster list in Scoreboard | Michael Camilleri | 2 | +8 | -10 |
| 2026-05-08 14:33 | Make roster always present | Michael Camilleri | 4 | +46 | -28 |
| 2026-05-08 13:58 | Add logging for rosters | Michael Camilleri | 1 | +18 | -0 |
| 2026-05-08 13:38 | Add alternative CloudKit path for notified changes | Michael Camilleri | 3 | +216 | -44 |
| 2026-05-08 13:25 | Use more targeted CloudKit fetches | Michael Camilleri | 2 | +18 | -11 |
| 2026-05-08 13:09 | Fetch current puzzle zone on push | Michael Camilleri | 2 | +45 | -6 |
| 2026-05-08 12:39 | Create push subscriptions expressly | Michael Camilleri | 1 | +52 | -0 |
| 2026-05-08 12:29 | Add more instrumentation to push notifications | Michael Camilleri | 1 | +33 | -0 |
| 2026-05-08 12:12 | Set APN environment to production | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-08 11:37 | Instrument notification code path | Michael Camilleri | 2 | +29 | -0 |
| 2026-05-08 07:54 | Push Moves immediately after debounced flush | Michael Camilleri | 3 | +49 | -12 |
| 2026-05-08 03:31 | Rewrite sync approach | Michael Camilleri | 32 | +1898 | -2210 |
| 2026-05-07 22:40 | Stop CKSyncEngine from looping on ZoneNotFound | Michael Camilleri | 3 | +260 | -4 |
| 2026-05-07 22:39 | Add testing instructions to AGENTS.md | Michael Camilleri | 1 | +9 | -0 |
| 2026-05-07 21:11 | Apply private-DB zone deletions on receiving devices | Michael Camilleri | 3 | +93 | -32 |
| 2026-05-07 20:31 | Recover from CloudKit etag drift on Player and Move records | Michael Camilleri | 3 | +49 | -1 |
| 2026-05-07 20:30 | Add basic AGENTS.md file | Michael Camilleri | 1 | +13 | -0 |
| 2026-05-07 10:26 | Add initial 10 bundled puzzles | Michael Camilleri | 15 | +1081 | -4 |
| 2026-05-07 09:49 | Move debug puzzles to new top-level directory | Michael Camilleri | 10 | +85 | -47 |
| 2026-05-07 08:09 | Support Across Lite puzzle import | Michael Camilleri | 9 | +569 | -8 |
| 2026-05-07 07:15 | Add external sources section to Settings | Michael Camilleri | 1 | +31 | -5 |
| 2026-05-07 05:36 | Fetch account e-mail through GraphQL profile | Michael Camilleri | 4 | +230 | -23 |
| 2026-05-07 04:41 | Add About screen to Settings | Michael Camilleri | 5 | +111 | -1 |
| 2026-05-06 23:21 | Fix silent record drops in inbound CloudKit sync | Michael Camilleri | 4 | +172 | -42 |
| 2026-05-06 21:58 | Replace in-memory engines on reset sync state | Michael Camilleri | 1 | +20 | -2 |
| 2026-05-06 19:31 | Propagate ckShareRecordName to other owner-devices | Michael Camilleri | 6 | +302 | -3 |
| 2026-05-06 18:30 | Fix XD accepted-answer rebus completion | Michael Camilleri | 3 | +117 | -8 |
| 2026-05-06 17:51 | Update text in notification messages | Michael Camilleri | 5 | +91 | -4 |
| 2026-05-06 17:38 | Tweak count on in-progress scoreboard on iPadOS | Michael Camilleri | 1 | +44 | -6 |
| 2026-05-06 17:34 | Improve final scoreboard display on iPadOS | Michael Camilleri | 1 | +20 | -6 |
| 2026-05-06 16:52 | Replace clear menu with entry menu | Michael Camilleri | 1 | +21 | -14 |
| 2026-05-06 16:22 | Fix concurrency warning about isolation | Michael Camilleri | 1 | +6 | -4 |
| 2026-05-06 15:51 | Support XD clue metadata accepted answers | Michael Camilleri | 7 | +503 | -27 |
| 2026-05-06 14:03 | Support additional iPad orientation | Michael Camilleri | 2 | +2 | -0 |
| 2026-05-06 13:56 | Change swipe gesture to change cursor axis to tap gesture | Michael Camilleri | 2 | +11 | -9 |
| 2026-05-06 13:17 | Add iPad portrait layout | Michael Camilleri | 2 | +97 | -18 |
| 2026-05-06 09:17 | Add external keyboard input handling | Michael Camilleri | 6 | +339 | -2 |
| 2026-05-06 04:23 | Add initial iPad layout | Michael Camilleri | 6 | +541 | -83 |
| 2026-05-06 01:20 | Add keyboard swipe to set entry direction | Michael Camilleri | 2 | +16 | -0 |
| 2026-05-06 00:07 | Preserve cell author on same-letter rewrites and reveal-of-correct | Michael Camilleri | 4 | +172 | -8 |
| 2026-05-05 22:16 | Expand scope of notifications of collaborator actions | Michael Camilleri | 9 | +247 | -97 |
| 2026-05-05 15:19 | Make GameStore collaborators required at construction | Michael Camilleri | 10 | +510 | -447 |
| 2026-05-05 11:43 | Persist local author identity across launches | Michael Camilleri | 4 | +45 | -15 |
| 2026-05-04 00:36 | Ensure notifications display during backgrounding | Michael Camilleri | 4 | +59 | -4 |
| 2026-05-04 00:01 | Prevent author tinting on empty squares | Michael Camilleri | 1 | +3 | -1 |
| 2026-05-03 23:54 | Tweak behaviour regarding shared games | Michael Camilleri | 1 | +16 | -3 |
| 2026-05-03 23:13 | Support author tinting on share | Michael Camilleri | 5 | +55 | -32 |
| 2026-05-03 22:58 | Update author tints dynamically | Michael Camilleri | 3 | +7 | -3 |
| 2026-05-03 05:31 | Use a faint background to differentiate authors | Michael Camilleri | 2 | +12 | -12 |
| 2026-05-03 04:20 | Add colours to text in shared games | Michael Camilleri | 2 | +20 | -3 |
| 2026-05-02 16:54 | Avoid using icons in puzzle view menus | Michael Camilleri | 1 | +3 | -9 |
| 2026-05-02 16:43 | Fix warnings about discarded results | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-02 16:42 | Fix leaving of shared games | Michael Camilleri | 1 | +9 | -2 |
| 2026-05-02 15:28 | Improve consistency between game list menu and puzzle menu | Michael Camilleri | 3 | +387 | -179 |
| 2026-05-02 15:06 | Simplify leave/deletion options for shared games | Michael Camilleri | 5 | +139 | -24 |
| 2026-05-02 11:29 | Unwind changes to reduce CloudKit calls | Michael Camilleri | 5 | +88 | -42 |
| 2026-05-02 08:25 | Remove performance logging | Michael Camilleri | 10 | +9 | -423 |
| 2026-05-02 08:13 | Fix needless game parsing on key strokes | Michael Camilleri | 5 | +156 | -28 |
| 2026-05-02 08:09 | Reenable ProMotion | Michael Camilleri | 2 | +3 | -0 |
| 2026-05-02 04:13 | Disable ProMotion | Michael Camilleri | 2 | +0 | -3 |
| 2026-05-02 01:36 | Allow certain logging to be disabled | Michael Camilleri | 5 | +109 | -55 |
| 2026-05-02 01:06 | Support toggling iCloud syncing | Michael Camilleri | 4 | +78 | -17 |
| 2026-05-02 00:52 | Increase granularity of logging | Michael Camilleri | 1 | +29 | -1 |
| 2026-05-02 00:42 | Make grid squares equatable | Michael Camilleri | 2 | +16 | -7 |
| 2026-05-02 00:06 | Add performance logging to SwiftUI-related functions | Michael Camilleri | 4 | +164 | -1 |
| 2026-05-01 23:22 | Reduce workload during flushes | Michael Camilleri | 3 | +122 | -4 |
| 2026-05-01 23:14 | Add more detail to performance logging | Michael Camilleri | 2 | +30 | -4 |
| 2026-05-01 23:06 | Add performance logging | Michael Camilleri | 10 | +429 | -91 |
| 2026-05-01 22:48 | Defer CloudKit move enqueues while typing | Michael Camilleri | 5 | +140 | -17 |
| 2026-05-01 22:41 | Reduce puzzle input work | Michael Camilleri | 4 | +92 | -9 |
| 2026-05-01 17:47 | Improve responsiveness in puzzle view | Michael Camilleri | 3 | +168 | -106 |
| 2026-05-01 16:32 | Reduce calculations during rendering | Michael Camilleri | 2 | +45 | -17 |
| 2026-05-01 13:54 | Improve scoreboard reveal | Michael Camilleri | 3 | +38 | -15 |
| 2026-05-01 13:14 | Add scoreboard to success panel | Michael Camilleri | 3 | +187 | -25 |
| 2026-05-01 11:47 | Recover existing CloudKit zone shares | Michael Camilleri | 1 | +95 | -14 |
| 2026-05-01 11:04 | Use panel rather than sheet on puzzle completion | Michael Camilleri | 2 | +30 | -37 |
| 2026-05-01 09:20 | Switch to using canvas for thumbnail previews | Michael Camilleri | 1 | +31 | -65 |
| 2026-05-01 08:54 | Tweak centring of puzzle again | Michael Camilleri | 1 | +1 | -0 |
| 2026-05-01 07:52 | Add separation between title and grid | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-01 07:37 | Adjust centring approach again | Michael Camilleri | 1 | +1 | -1 |
| 2026-05-01 07:28 | Adjust centring approach | Michael Camilleri | 1 | +34 | -28 |
| 2026-05-01 04:35 | Centre grid in puzzle view | Michael Camilleri | 1 | +119 | -47 |
| 2026-04-30 23:45 | Support high refresh rates | Michael Camilleri | 2 | +3 | -0 |
| 2026-04-30 23:33 | Detect more forms of cross-referenced clues | Michael Camilleri | 2 | +127 | -11 |
| 2026-04-30 22:04 | Make last update time update live | Michael Camilleri | 1 | +37 | -5 |
| 2026-04-30 21:52 | Change display of cross-referenced clues | Michael Camilleri | 5 | +218 | -73 |
| 2026-04-30 21:50 | Add scripts to translate JSON to XD | Michael Camilleri | 3 | +128 | -0 |
| 2026-04-30 12:51 | Change reveal tool to only mark mistakes as correct | Michael Camilleri | 2 | +41 | -2 |
| 2026-04-30 05:05 | Tweak threshhold for roomier display | Michael Camilleri | 1 | +1 | -1 |
| 2026-04-30 05:00 | Make game list styling dependent on scene size | Michael Camilleri | 1 | +59 | -38 |
| 2026-04-30 04:36 | Change date formatting in PuzzleView | Michael Camilleri | 1 | +2 | -2 |
| 2026-04-30 04:30 | Tweak game list styling | Michael Camilleri | 1 | +75 | -14 |
| 2026-04-30 04:17 | Show unread badge for unseen shared puzzle changes | Michael Camilleri | 6 | +186 | -4 |
| 2026-04-30 03:55 | Navigate to games from notification taps | Michael Camilleri | 1 | +52 | -0 |
| 2026-04-30 03:43 | Remove remote-alert notification path | Michael Camilleri | 11 | +11 | -404 |
| 2026-04-30 02:30 | Use synced pings for activity notifications | Michael Camilleri | 3 | +103 | -35 |
| 2026-04-29 14:30 | Add app notifications for shared puzzle activity | Michael Camilleri | 15 | +738 | -10 |
| 2026-04-29 12:50 | Use grey for thematic colouring | Michael Camilleri | 1 | +2 | -2 |
| 2026-04-29 10:34 | Add Crossmake tool | Michael Camilleri | 6 | +355703 | -0 |
| 2026-04-29 07:32 | Fix 'ghost' player in roster | Michael Camilleri | 1 | +2 | -1 |
| 2026-04-29 04:44 | Fix name broadcasting in share puzzles | Michael Camilleri | 6 | +70 | -15 |
| 2026-04-28 23:34 | Drop parent references from Move, Snapshot and Player records | Michael Camilleri | 3 | +2 | -52 |
| 2026-04-28 23:24 | Show peer cursor in shared puzzles | Michael Camilleri | 15 | +718 | -15 |
| 2026-04-28 17:37 | Add more logging for shared games | Michael Camilleri | 3 | +77 | -14 |
| 2026-04-28 09:05 | Add poll-based synchronisation when inside puzzle | Michael Camilleri | 2 | +30 | -0 |
| 2026-04-28 05:52 | Treat italicised clues as related group | Michael Camilleri | 3 | +94 | -6 |
| 2026-04-28 05:11 | Add CloudKit shares to a queue on launch | Michael Camilleri | 3 | +60 | -51 |
| 2026-04-28 03:46 | Fix handling of shared games from links | Michael Camilleri | 3 | +64 | -2 |
| 2026-04-28 03:44 | Tweak display of puzzles in GameListView | Michael Camilleri | 7 | +88 | -21 |
| 2026-04-28 02:49 | Fix puzzle timestamp updating | Michael Camilleri | 3 | +35 | -0 |
| 2026-04-28 02:35 | Avoid flash as iCloud link is checked | Michael Camilleri | 1 | +1 | -1 |
| 2026-04-28 02:25 | Use existing link in share sheet | Michael Camilleri | 2 | +58 | -2 |
| 2026-04-28 02:14 | Tweak share sheet | Michael Camilleri | 1 | +3 | -10 |
| 2026-04-28 01:17 | Replace share sheet with link creation sheet | Michael Camilleri | 9 | +482 | -252 |
| 2026-04-28 00:11 | Fix share link creation | Michael Camilleri | 3 | +111 | -31 |
| 2026-04-27 00:31 | Revert to previous share sheet | Michael Camilleri | 5 | +23 | -157 |
| 2026-04-27 00:10 | Gate share button | Michael Camilleri | 5 | +157 | -23 |
| 2026-04-26 23:47 | Switch share sheet to ShareLink | Michael Camilleri | 6 | +83 | -110 |
| 2026-04-26 12:44 | Improve display of share sheet | Michael Camilleri | 1 | +13 | -3 |
| 2026-04-26 11:03 | Extract CloudService and ImportService from AppServices | Michael Camilleri | 7 | +161 | -119 |
| 2026-04-26 10:43 | Remove unnecessary lock | Michael Camilleri | 6 | +18 | -49 |
| 2026-04-26 10:25 | Tighten up tests | Michael Camilleri | 6 | +76 | -47 |
| 2026-04-26 05:03 | Add missing tests and fix colour cleanup on game delete | Michael Camilleri | 8 | +465 | -5 |
| 2026-04-26 02:29 | Use shorter identifiers | Michael Camilleri | 4 | +14 | -14 |
| 2026-04-26 02:23 | Defer snapshot move pruning until upload succeeds | Michael Camilleri | 6 | +226 | -13 |
| 2026-04-26 02:09 | Unify CKContainer instances | Michael Camilleri | 1 | +2 | -3 |
| 2026-04-26 01:55 | Share player names in multiplayer | Michael Camilleri | 12 | +971 | -15 |
| 2026-04-24 19:12 | Add CKShare sharing via per-game zones and dual sync engines | Michael Camilleri | 20 | +1088 | -176 |
| 2026-04-24 09:08 | Make iCloud error recording asynchronous | Michael Camilleri | 1 | +13 | -4 |
| 2026-04-24 08:01 | Add reset database button to Settings | Michael Camilleri | 2 | +19 | -20 |
| 2026-04-24 07:57 | Fix gaps in synchronisation logic | Michael Camilleri | 2 | +16 | -0 |
| 2026-04-24 04:06 | Fix correctness issues in new data flow | Michael Camilleri | 4 | +43 | -13 |
| 2026-04-24 03:46 | Improve snapshots creation | Michael Camilleri | 9 | +224 | -29 |
| 2026-04-23 21:53 | Ensure that list previews are up to date | Michael Camilleri | 3 | +54 | -1 |
| 2026-04-23 21:35 | Adopt move-log architecture and CKSyncEngine | Michael Camilleri | 21 | +1135 | -2444 |
| 2026-04-22 09:36 | Begin process of moving to snapshots and move log | Michael Camilleri | 5 | +588 | -0 |
| 2026-04-22 09:19 | Improve throttle avoidance | Michael Camilleri | 6 | +222 | -17 |
| 2026-04-22 09:00 | Avoid data loss caused by pending updates | Michael Camilleri | 2 | +210 | -0 |
| 2026-04-21 23:11 | Support shaded cells in certain crosswords | Michael Camilleri | 1 | +64 | -2 |
| 2026-04-21 21:59 | Change version format | Michael Camilleri | 2 | +2 | -2 |
| 2026-04-21 21:48 | Use clue list to display long clues | Michael Camilleri | 4 | +94 | -1 |
| 2026-04-21 20:52 | Support relative relationships between clues | Michael Camilleri | 7 | +364 | -1 |
| 2026-04-21 19:25 | Provide feedback to user when puzzle is filled in | Michael Camilleri | 2 | +94 | -0 |
| 2026-04-21 19:07 | Support direction toggle via the Clue Bar | Michael Camilleri | 1 | +4 | -0 |
| 2026-04-21 19:02 | Fix auto-advancing | Michael Camilleri | 1 | +19 | -7 |
| 2026-04-17 20:26 | Tweak app icon | Michael Camilleri | 2 | +0 | -0 |
| 2026-04-17 10:04 | Revert Clue Bar to having a dynamic height | Michael Camilleri | 1 | +0 | -5 |
| 2026-04-17 09:42 | Fix clue sliding | Michael Camilleri | 1 | +23 | -23 |
| 2026-04-17 09:13 | Add padding above custom keyboard | Michael Camilleri | 1 | +1 | -0 |
| 2026-04-17 08:32 | Add draft toggling to the keyboard overflow | Michael Camilleri | 1 | +12 | -1 |
| 2026-04-17 08:26 | Display location in all caps | Michael Camilleri | 1 | +1 | -0 |
| 2026-04-17 08:21 | Tweak change name alert | Michael Camilleri | 1 | +4 | -0 |
| 2026-04-17 06:51 | Tidy up naming | Michael Camilleri | 1 | +10 | -15 |
| 2026-04-17 06:32 | Rename UbiquityMonitor to DriveMonitor | Michael Camilleri | 6 | +294 | -294 |
| 2026-04-17 05:52 | Inject sync services via environment | Michael Camilleri | 5 | +15 | -12 |
| 2026-04-17 03:24 | Improve separation of concerns in architecture | Michael Camilleri | 10 | +265 | -180 |
| 2026-04-14 22:58 | Ensure Core Data changes are sent to iCloud | Michael Camilleri | 6 | +221 | -19 |
| 2026-04-14 17:32 | Sync deletion of games | Michael Camilleri | 4 | +181 | -24 |
| 2026-04-14 17:19 | Ensure game creation triggers iCloud sync | Michael Camilleri | 2 | +31 | -9 |
| 2026-04-14 17:04 | Refactor to use @FetchRequest | Michael Camilleri | 5 | +86 | -139 |
| 2026-04-14 16:00 | Support repairing of broken games | Michael Camilleri | 1 | +52 | -0 |
| 2026-04-14 15:20 | Attempt to address missing entity ID | Michael Camilleri | 1 | +26 | -5 |
| 2026-04-14 14:38 | Change gating logic for iCloud fetches | Michael Camilleri | 1 | +13 | -9 |
| 2026-04-14 14:03 | Add telemetry for iCloud debugging | Michael Camilleri | 1 | +26 | -2 |
| 2026-04-14 13:36 | Ensure zone ID is known before pushes and fetches | Michael Camilleri | 1 | +31 | -2 |
| 2026-04-14 11:59 | Remove Crossmate heading | Michael Camilleri | 1 | +8 | -3 |
| 2026-04-14 10:04 | Clarify scope of XD file support | Michael Camilleri | 2 | +3 | -0 |
| 2026-04-14 09:52 | Improve support for importing XD puzzles | Michael Camilleri | 6 | +118 | -1 |
| 2026-04-14 09:42 | Improve robustness of puzzle selection | Michael Camilleri | 6 | +90 | -23 |
| 2026-04-14 05:06 | Add player menu | Michael Camilleri | 3 | +87 | -4 |
| 2026-04-14 00:23 | Add submit button to calendar picker | Michael Camilleri | 2 | +49 | -4 |
| 2026-04-13 23:20 | Add date field to XD struct | Michael Camilleri | 6 | +34 | -24 |
| 2026-04-13 21:26 | Change colours used in clue bar and start squares | Michael Camilleri | 3 | +35 | -7 |
| 2026-04-13 09:51 | Add support for external puzzles | Michael Camilleri | 8 | +357 | -45 |
| 2026-04-12 23:39 | Ensure game records are saved before square records | Michael Camilleri | 3 | +103 | -33 |
| 2026-04-12 21:39 | Expand instrumentation of sync logic | Michael Camilleri | 2 | +87 | -6 |
| 2026-04-12 19:54 | Switch to different iCloud container | Michael Camilleri | 2 | +3 | -1 |
| 2026-04-12 19:42 | Add write probe as part of iCloud debugging support | Michael Camilleri | 1 | +42 | -0 |
| 2026-04-12 17:29 | Add even more iCloud debugging support | Michael Camilleri | 3 | +56 | -1 |
| 2026-04-12 17:09 | Add more iCloud debugging support | Michael Camilleri | 2 | +28 | -0 |
| 2026-04-12 15:36 | Add sync monitor | Michael Camilleri | 7 | +346 | -15 |
| 2026-04-12 11:17 | Ensure placeholder file is added to iCloud Drive | Michael Camilleri | 1 | +12 | -0 |
| 2026-04-12 08:13 | Set initial version to 1.0 | Michael Camilleri | 4 | +46 | -4 |
| 2026-04-12 07:52 | Add support for additional puzzle sources | Michael Camilleri | 17 | +675 | -10 |
| 2026-04-12 02:09 | Settings and NYT authentication | Michael Camilleri | 9 | +740 | -0 |
| 2026-04-11 10:20 | Add puzzle catalog | Michael Camilleri | 11 | +791 | -80 |
| 2026-04-11 10:14 | Add CloudKit-based sync engine | Michael Camilleri | 23 | +2011 | -129 |
| 2026-04-09 21:22 | Add persistence | Michael Camilleri | 6 | +298 | -3 |
| 2026-04-09 21:06 | Add support for specials | Michael Camilleri | 4 | +51 | -16 |
| 2026-04-09 20:55 | Add initial prototype | Michael Camilleri | 19 | +2291 | -0 |
| 2026-04-08 22:53 | Initial commit | Michael Camilleri | 1 | +10 | -0 |