F-01 (P1): _buildGpsFiltersUI больше не хардкодит список источников — подтягивает source_id из /api/gps-tracks/health.tracks_by_source (ADR-013 §3 Решение D, опция D2). Маппинг source_id → label вынесен в JS-константу GPS_SOURCE_LABELS. Активация четвёртого источника теперь не требует изменений в этом коде. F-02 (P1): attribution фиксируется в момент addSource, а не мутацией src.attribution после. MapLibre AttributionControl не реагирует на прямое присвоение — потому до этого фикса AC-15 проваливался бы в UI-тестах. Теперь onPublicTracksCheckbox / restorePublicTracksState сначала await _fetchGpsHealth() → _buildGpsAttributionString(), потом _ensureGpsSources(map, attribution). Добавлен кэш + in-flight Promise (window.gpsTracksLayer._healthCache / _healthFetchPromise) — переоткрытие sheet'а фильтров не плодит дублирующих сетевых запросов. Все 24 node-теста gps_tracks.test.js зелёные. Refs: ET-009 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>