@@ -34,7 +34,7 @@ extension UsageStore {
3434 phaseDidChange ? ( . credits)
3535
3636 if self . settings. codexCookieSource. isEnabled {
37- let expectedGuard = self . currentCodexAccountScopedRefreshGuard ( )
37+ let expectedGuard = self . currentCodexOpenAIWebRefreshGuard ( )
3838 await self . refreshOpenAIDashboardIfNeeded (
3939 force: true ,
4040 expectedGuard: expectedGuard,
@@ -76,6 +76,7 @@ extension UsageStore {
7676 self . lastCreditsError = nil
7777 self . lastCreditsSnapshot = nil
7878 self . lastCreditsSnapshotAccountKey = nil
79+ self . lastCreditsSource = . none
7980 self . creditsFailureStreak = 0
8081
8182 self . clearCodexOpenAIWebStateForAccountTransition ( targetEmail: self . codexAccountEmailForOpenAIDashboard ( ) )
@@ -179,31 +180,106 @@ extension UsageStore {
179180 return currentGuard. identity == expectedGuard. identity
180181 }
181182
182- func shouldApplyOpenAIDashboardResult (
183+ func shouldApplyOpenAIDashboardRefreshGuard (
183184 expectedGuard: CodexAccountScopedRefreshGuard ,
184- dashboardAccountEmail : String ? ) -> Bool
185+ routingTargetEmail : String ? ) -> Bool
185186 {
187+ let normalizedRoutingTargetEmail = CodexIdentityResolver . normalizeEmail ( routingTargetEmail)
188+ let currentGuard = self . currentCodexOpenAIWebRefreshGuard ( )
189+ guard currentGuard. source == expectedGuard. source else { return false }
190+
186191 if expectedGuard. identity != . unresolved {
187- let currentGuard = self . currentCodexAccountScopedRefreshGuard ( )
188- guard currentGuard. source == expectedGuard. source else { return false }
189192 return currentGuard. identity == expectedGuard. identity
190193 }
191194
192- let currentGuard = self . currentCodexOpenAIWebRefreshGuard ( )
193- guard currentGuard. source == expectedGuard. source else { return false }
194195 guard case . liveSystem = expectedGuard. source else { return false }
195196 guard currentGuard. identity == . unresolved else { return false }
196- let dashboardIdentity = CodexIdentityResolver . resolve ( accountId: nil , email: dashboardAccountEmail)
197- guard dashboardIdentity != . unresolved else { return false }
198- let currentTargetIdentity = CodexIdentityResolver . resolve (
199- accountId: nil ,
200- email: self . currentCodexOpenAIWebTargetEmail (
197+ return CodexIdentityResolver . normalizeEmail (
198+ self . currentCodexOpenAIWebTargetEmail (
201199 allowCurrentSnapshotFallback: true ,
202- allowLastKnownLiveFallback: false ) )
203- if currentTargetIdentity != . unresolved {
204- return dashboardIdentity == currentTargetIdentity
200+ allowLastKnownLiveFallback: false ) ) == normalizedRoutingTargetEmail
201+ }
202+
203+ func shouldApplyOpenAIWebNonSuccessResult(
204+ expectedGuard: CodexAccountScopedRefreshGuard ,
205+ routingTargetEmail: String ? ) -> Bool
206+ {
207+ self . shouldApplyOpenAIDashboardRefreshGuard (
208+ expectedGuard: expectedGuard,
209+ routingTargetEmail: routingTargetEmail)
210+ }
211+
212+ func codexDashboardKnownOwnerCandidates( ) -> [ CodexDashboardKnownOwnerCandidate ] {
213+ let snapshot = self . settings. codexAccountReconciliationSnapshot
214+ var candidates = snapshot. storedAccounts. map { account in
215+ CodexDashboardKnownOwnerCandidate (
216+ identity: snapshot. runtimeIdentity ( for: account) ,
217+ normalizedEmail: CodexIdentityResolver . normalizeEmail ( snapshot. runtimeEmail ( for: account) ) )
205218 }
206- return true
219+
220+ if let liveSystemAccount = snapshot. liveSystemAccount {
221+ candidates. append ( CodexDashboardKnownOwnerCandidate (
222+ identity: snapshot. runtimeIdentity ( for: liveSystemAccount) ,
223+ normalizedEmail: CodexIdentityResolver . normalizeEmail ( liveSystemAccount. email) ) )
224+ }
225+
226+ return candidates
227+ }
228+
229+ func trustedCurrentCodexUsageEmailForDashboardAuthority( ) -> String ? {
230+ guard let sourceLabel = self . lastSourceLabels [ . codex] , sourceLabel != " openai-web " else {
231+ return nil
232+ }
233+ return CodexIdentityResolver . normalizeEmail ( self . snapshots [ . codex] ? . accountEmail ( for: . codex) )
234+ }
235+
236+ func currentCodexDashboardExpectedScopedEmail( ) -> String ? {
237+ switch self . settings. codexResolvedActiveSource {
238+ case . liveSystem:
239+ CodexIdentityResolver . normalizeEmail (
240+ self . settings. codexAccountReconciliationSnapshot. liveSystemAccount? . email)
241+ case . managedAccount:
242+ CodexIdentityResolver . normalizeEmail ( self . currentManagedCodexRuntimeEmail ( ) )
243+ }
244+ }
245+
246+ func makeCodexDashboardAuthorityInput(
247+ dashboard: OpenAIDashboardSnapshot ,
248+ sourceKind: CodexDashboardSourceKind ,
249+ routingTargetEmail: String ? ) -> CodexDashboardAuthorityInput
250+ {
251+ let source = self . settings. codexResolvedActiveSource
252+ return CodexDashboardAuthorityInput (
253+ sourceKind: sourceKind,
254+ proof: CodexDashboardOwnershipProofContext (
255+ currentIdentity: self . currentCodexOpenAIWebIdentity ( source: source) ,
256+ expectedScopedEmail: self . currentCodexDashboardExpectedScopedEmail ( ) ,
257+ trustedCurrentUsageEmail: self . trustedCurrentCodexUsageEmailForDashboardAuthority ( ) ,
258+ dashboardSignedInEmail: dashboard. signedInEmail,
259+ knownOwners: self . codexDashboardKnownOwnerCandidates ( ) ) ,
260+ routing: CodexDashboardRoutingHints (
261+ targetEmail: CodexIdentityResolver . normalizeEmail ( routingTargetEmail) ,
262+ lastKnownDashboardRoutingEmail: CodexIdentityResolver . normalizeEmail (
263+ self . lastKnownLiveSystemCodexEmail) ) )
264+ }
265+
266+ func evaluateCodexDashboardAuthority(
267+ dashboard: OpenAIDashboardSnapshot ,
268+ sourceKind: CodexDashboardSourceKind ,
269+ routingTargetEmail: String ? ) -> ( input: CodexDashboardAuthorityInput , decision: CodexDashboardAuthorityDecision )
270+ {
271+ let input = self . makeCodexDashboardAuthorityInput (
272+ dashboard: dashboard,
273+ sourceKind: sourceKind,
274+ routingTargetEmail: routingTargetEmail)
275+ return ( input, CodexDashboardAuthority . evaluate ( input) )
276+ }
277+
278+ func codexDashboardAttachmentEmail( from input: CodexDashboardAuthorityInput ) -> String ? {
279+ CodexIdentityResolver . normalizeEmail (
280+ input. proof. expectedScopedEmail ??
281+ input. proof. trustedCurrentUsageEmail ??
282+ input. proof. dashboardSignedInEmail)
207283 }
208284
209285 func rememberLiveSystemCodexEmailIfNeeded( _ email: String ? ) {
0 commit comments