# 1.1.0 external ui_config.json discovery and merge > Version: 1.1.0. Release requirements; implementation and delivery are recorded below. > [Verification status](/Riff/1-1-0/status). ## Location and admission Search for ui_config.json in the same directory as the Riff volume marker: .riff/ui_config.json alongside .riff/riff_root_uuid and riff_root_uuid.xxh3 in each accessible, admitted persisted SAF source tree. This is user-accessible media storage, not Android's private Application Directory. Do not read player/ui_config.json as a second source or compatibility fallback. Discover all such configuration documents through supported SAF enumeration and provider-issued locators. Never fabricate document IDs or infer physical paths. Normal media traversal still excludes dot directories; configuration/marker discovery is an explicit scoped read and does not index .riff. Read every discovered candidate, including read-only trees. Absence is normal. No grant acquisition, marker creation or root mutation is authorized merely to read configuration. Marker validity and its existing fallback behavior remain separately controlled; a discoverable config document is not a validated volume UUID. An unavailable root contributes no currently readable overlay. ## Merge without promised precedence Deep-merge every discovered valid user document into one aggregate user overlay. Enumeration/merge order is deliberately unspecified: no root order, filename precedence, lexical URI order, volume priority or last-mounted priority is promised. Objects merge recursively; arrays replace; scalar leaves replace; null does not delete. For conflicting leaves, later encountered input replaces earlier input in that particular startup, but which file is encountered later is not guaranteed. Users must not rely on conflicting files for deterministic precedence. Do not silently change this to first-file-only or conflict rejection. Validate each document's syntax and allowed structure/types, merge all user inputs, then validate the complete effective configuration, including every named skin. A malformed/unreadable discovered candidate or invalid effective set rejects the entire external overlay set and uses packaged defaults with one bounded diagnostic. Mere absence is not an error. Partial documents may complement one another before complete semantic validation. After aggregation, retain the existing skin layering: packaged default -> packaged active skin -> aggregate user default -> aggregate user active skin. schemaVersion remains 3; partial input may inherit it. Unknown keys, null, unsupported versions, unsafe variants and invalid final values remain errors. ## One coherent startup The shared :configuration module remains the only parser/merge/validation owner. Android adapters only discover/read provider documents. No consumer-specific parser, Settings JSON editor, file watcher or hot reload is added. Perform configuration discovery after selected application-data-root admission but before starting dependent UI/playback/indexing work. Both processes must use the same frozen discovery result and effective snapshot within one running application session; independently unspecified orders must not give Player and Indexer contradictory settings. The startup coordinator hands off the same aggregate bytes/content ID. A reconnecting endpoint adopts the live session's snapshot; a fresh application session discovers again. No persistent private-directory config copy is a new authority. Activity recreation, focus return, theme changes and resizing use the cached snapshot. New grants, mounts or edited files affect a fresh application startup. Bootstrap-only recovery UI uses its established safe defaults/cache until selected-root admission succeeds.