Found during the release audit (economy-schema V10 + the reconciliation cron).
explorer_group_member PK is (group_id, player_uuid_bin) with no source, so a (group, player) pair can exist at most once. If an admin manually adds player P to a group (source='manual') and P also carries the group's LuckPerms node, the cron's INSERT IGNORE ... 'luckperms' is silently no-op'd by the PK collision. Consequences:
listLuckpermsMemberUuids (filtered to source='luckperms'), so the cron's diff never converges for P — it re-attempts the (ignored) insert every run forever (harmless thrash).The "never clobber manual" invariant still holds (INSERT IGNORE won't overwrite, DELETE filters on source). Capability resolution unions groups so P still gets the group's caps via the manual row — functionally fine, just non-converging churn.
Fix: make the PK/UNIQUE include source in a new economy-schema migration ((group_id, player_uuid_bin, source)), and update the explorer read query if it assumes one row per (group, player). Or, if two-source membership isn't wanted, document that manual masks luckperms by design and have the cron skip players already present via another source.