resolveProviderQueueScopes function
Resolves the queue across scopes: env > project > user > legacy.
Pass one ProviderQueueScopeInput per scope in any order; only present
scopes matter. When none is present the result is unset (the legacy
provider:+model: boot continues byte-identical — AC10).
Shadowed scopes are named in the notices (AC2); a shadowed scope whose queue is semantically identical to the winner collapses into the winner's notice (UT-scope-stack: "project+user identical queues → single notice, no dupes").
Implementation
ProviderQueueResolution resolveProviderQueueScopes(
List<ProviderQueueScopeInput> inputs,
) {
final present = inputs.where((input) => input.isPresent).toList()
..sort((a, b) => a.scope.index.compareTo(b.scope.index));
if (present.isEmpty) {
return const ProviderQueueResolution(
scope: ProviderQueueScope.user,
entries: [],
notices: [],
);
}
final winner = present.first;
final entries = winner.parse?.entries ?? const <ProviderQueueEntry>[];
final notices = <String>[
'note: provider queue (${entries.length} '
'${entries.length == 1 ? 'entry' : 'entries'}) from '
'${_scopeLabel(winner.scope)} — the queue is the main model',
];
final shadowed = present.sublist(1);
for (final scope in shadowed) {
final sameQueue = _sameEntries(scope.parse?.entries, entries);
notices.add(
sameQueue
? 'note: provider queue — ${_scopeLabel(scope.scope)} declares the '
'same queue (shadowed, no duplicate)'
: 'note: provider queue — ${_scopeLabel(scope.scope)} is shadowed '
'by ${_scopeLabel(winner.scope)}',
);
}
return ProviderQueueResolution(
scope: winner.scope,
entries: entries,
notices: notices,
);
}