import CodexBarCoreimport Foundation enum HistoricalUsageWindowKind: String, Codable { case secondary} enum HistoricalUsageRecordSource: String, Codable { case live case backfill} struct HistoricalUsageRecord: Codable { let v: Int let provider: UsageProvider let windowKind: HistoricalUsageWindowKind let source: HistoricalUsageRecordSource let accountKey: String? let sampledAt: Date let usedPercent: Double let resetsAt: Date let windowMinutes: Int init( v: Int, provider: UsageProvider, windowKind: HistoricalUsageWindowKind, source: HistoricalUsageRecordSource, accountKey: String?, sampledAt: Date, usedPercent: Double, resetsAt: Date, windowMinutes: Int) { self.v = v self.provider = provider self.windowKind = windowKind self.source = source self.accountKey = accountKey self.sampledAt = sampledAt self.usedPercent = usedPercent self.resetsAt = resetsAt self.windowMinutes = windowMinutes } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.v = try container.decodeIfPresent(Int.self, forKey: .v) ?? 1 self.provider = try container.decode(UsageProvider.self, forKey: .provider) self.windowKind = try container.decode(HistoricalUsageWindowKind.self, forKey: .windowKind) self.source = try container.decodeIfPresent(HistoricalUsageRecordSource.self, forKey: .source) ?? .live self.accountKey = try container.decodeIfPresent(String.self, forKey: .accountKey) self.sampledAt = try container.decode(Date.self, forKey: .sampledAt) self.usedPercent = try container.decode(Double.self, forKey: .usedPercent) self.resetsAt = try container.decode(Date.self, forKey: .resetsAt) self.windowMinutes = try container.decode(Int.self, forKey: .windowMinutes) }} struct HistoricalWeekProfile { let resetsAt: Date let windowMinutes: Int let curve: [Double]} struct CodexHistoricalDataset { static let gridPointCount = 169 let weeks: [HistoricalWeekProfile]} actor HistoricalUsageHistoryStore { private static let schemaVersion = 1 private static let writeInterval: TimeInterval = 30 * 60 private static let writeDeltaThreshold: Double = 1 private static let retentionDays: TimeInterval = 56 * 24 * 60 * 60 private static let minimumWeekSamples = 6 private static let boundaryCoverageWindow: TimeInterval = 24 * 60 * 60 private static let backfillWindowCapWeeks = 8 private static let backfillCalibrationMinimumUsedPercent = 1.0 private static let backfillCalibrationMinimumCredits = 0.001 private static let backfillSampleFractions: [Double] = (0...14).map { Double($0) / 14.0 } private static let coverageTolerance: TimeInterval = 16 * 60 * 60 private static let resetBucketSeconds: TimeInterval = 5 * 60 private let fileURL: URL private var records: [HistoricalUsageRecord] = [] private var loaded = false init(fileURL: URL? = nil) { self.fileURL = fileURL ?? HistoricalUsageHistoryStore.defaultFileURL() } func loadCodexDataset(accountKey: String?) -> CodexHistoricalDataset? { self.ensureLoaded() return self.buildDataset(accountKey: accountKey) } func loadCodexDataset( canonicalAccountKey: String?, canonicalEmailHashKey: String?, legacyEmailHash: String?, hasAdjacentMultiAccountVeto: Bool) -> CodexHistoricalDataset? { self.ensureLoaded() return self.buildDataset( canonicalAccountKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey, legacyEmailHash: legacyEmailHash, hasAdjacentMultiAccountVeto: hasAdjacentMultiAccountVeto) } func recordCodexWeekly( window: RateWindow, sampledAt: Date = .init(), accountKey: String?) -> CodexHistoricalDataset? { guard let rawResetsAt = window.resetsAt else { return self.loadCodexDataset(accountKey: accountKey) } guard let windowMinutes = window.windowMinutes, windowMinutes > 0 else { return self.loadCodexDataset(accountKey: accountKey) } self.ensureLoaded() let resetsAt = Self.normalizeReset(rawResetsAt) let sample = HistoricalUsageRecord( v: Self.schemaVersion, provider: .codex, windowKind: .secondary, source: .live, accountKey: accountKey, sampledAt: sampledAt, usedPercent: Self.clamp(window.usedPercent, lower: 0, upper: 100), resetsAt: resetsAt, windowMinutes: windowMinutes) if !self.shouldAccept(sample) { return self.buildDataset(accountKey: accountKey) } self.records.append(sample) self.pruneOldRecords(now: sampledAt) self.records.sort { lhs, rhs in if lhs.sampledAt == rhs.sampledAt { if lhs.resetsAt == rhs.resetsAt { return lhs.usedPercent < rhs.usedPercent } return lhs.resetsAt < rhs.resetsAt } return lhs.sampledAt < rhs.sampledAt } self.persist() return self.buildDataset(accountKey: accountKey) } func backfillCodexWeeklyFromUsageBreakdown( _ breakdown: [OpenAIDashboardDailyBreakdown], referenceWindow: RateWindow, now: Date = .init(), accountKey: String?) -> CodexHistoricalDataset? { self.ensureLoaded() let existingDataset = self.buildDataset(accountKey: accountKey) guard let rawResetsAt = referenceWindow.resetsAt else { return existingDataset } guard let windowMinutes = referenceWindow.windowMinutes, windowMinutes > 0 else { return existingDataset } let resetsAt = Self.normalizeReset(rawResetsAt) let duration = TimeInterval(windowMinutes) * 60 guard duration > 0 else { return existingDataset } let windowStart = resetsAt.addingTimeInterval(-duration) let calibrationEnd = Self.clampDate(now, lower: windowStart, upper: resetsAt) let dayUsages = Self.parseDayUsages( from: breakdown, asOf: calibrationEnd, fillingFrom: windowStart) guard !dayUsages.isEmpty else { return existingDataset } guard let coverageStart = dayUsages.first?.start, let coverageEnd = dayUsages.last?.end else { return existingDataset } guard coverageStart <= windowStart.addingTimeInterval(Self.coverageTolerance) else { return existingDataset } guard coverageEnd >= calibrationEnd.addingTimeInterval(-Self.coverageTolerance) else { return existingDataset } let currentUsedPercent = Self.clamp(referenceWindow.usedPercent, lower: 0, upper: 100) guard currentUsedPercent >= Self.backfillCalibrationMinimumUsedPercent else { return existingDataset } let currentCredits = Self.creditsUsed( from: dayUsages, between: windowStart, and: calibrationEnd) guard currentCredits > Self.backfillCalibrationMinimumCredits else { return existingDataset } let estimatedCreditsAtLimit = currentCredits / (currentUsedPercent / 100) guard estimatedCreditsAtLimit.isFinite, estimatedCreditsAtLimit > Self.backfillCalibrationMinimumCredits else { return existingDataset } struct RecordKey: Hashable { let resetsAt: Date let sampledAt: Date let windowMinutes: Int let accountKey: String? } var synthesized: [HistoricalUsageRecord] = [] synthesized.reserveCapacity(Self.backfillWindowCapWeeks * Self.backfillSampleFractions.count) for weeksBack in 1...Self.backfillWindowCapWeeks { let reset = Self.normalizeReset(resetsAt.addingTimeInterval(-duration * Double(weeksBack))) let start = reset.addingTimeInterval(-duration) guard start >= coverageStart.addingTimeInterval(-Self.coverageTolerance), reset <= coverageEnd.addingTimeInterval(Self.coverageTolerance) else { continue } let existingForWeek = self.records.filter { $0.provider == .codex && $0.windowKind == .secondary && $0.windowMinutes == windowMinutes && $0.accountKey == accountKey && $0.resetsAt == reset } if Self.isCompleteWeek(samples: existingForWeek, windowStart: start, resetsAt: reset) { continue } var existingRecordKeys = Set(existingForWeek.map { RecordKey( resetsAt: $0.resetsAt, sampledAt: $0.sampledAt, windowMinutes: $0.windowMinutes, accountKey: $0.accountKey) }) let weekCredits = Self.creditsUsed(from: dayUsages, between: start, and: reset) guard weekCredits > Self.backfillCalibrationMinimumCredits else { continue } for fraction in Self.backfillSampleFractions { let sampledAt = start.addingTimeInterval(duration * fraction) let recordKey = RecordKey( resetsAt: reset, sampledAt: sampledAt, windowMinutes: windowMinutes, accountKey: accountKey) guard !existingRecordKeys.contains(recordKey) else { continue } let cumulativeCredits = Self.creditsUsed(from: dayUsages, between: start, and: sampledAt) let usedPercent = Self.clamp((cumulativeCredits / estimatedCreditsAtLimit) * 100, lower: 0, upper: 100) synthesized.append(HistoricalUsageRecord( v: Self.schemaVersion, provider: .codex, windowKind: .secondary, source: .backfill, accountKey: accountKey, sampledAt: sampledAt, usedPercent: usedPercent, resetsAt: reset, windowMinutes: windowMinutes)) existingRecordKeys.insert(recordKey) } } guard !synthesized.isEmpty else { return existingDataset } self.records.append(contentsOf: synthesized) self.pruneOldRecords(now: now) self.records.sort { lhs, rhs in if lhs.sampledAt == rhs.sampledAt { if lhs.resetsAt == rhs.resetsAt { return lhs.usedPercent < rhs.usedPercent } return lhs.resetsAt < rhs.resetsAt } return lhs.sampledAt < rhs.sampledAt } self.persist() return self.buildDataset(accountKey: accountKey) } private func shouldAccept(_ sample: HistoricalUsageRecord) -> Bool { guard let prior = self.records .last(where: { $0.provider == sample.provider && $0.windowKind == sample.windowKind && $0.accountKey == sample.accountKey && $0.windowMinutes == sample.windowMinutes }) else { return true } if prior.resetsAt != sample.resetsAt { return true } if sample.sampledAt.timeIntervalSince(prior.sampledAt) >= Self.writeInterval { return true } if abs(sample.usedPercent - prior.usedPercent) >= Self.writeDeltaThreshold { return true } return false } private func pruneOldRecords(now: Date) { let cutoff = now.addingTimeInterval(-Self.retentionDays) self.records.removeAll { $0.sampledAt < cutoff } } private func ensureLoaded() { guard !self.loaded else { return } self.loaded = true self.records = self.readRecordsFromDisk() self.pruneOldRecords(now: .init()) } private func readRecordsFromDisk() -> [HistoricalUsageRecord] { guard let data = try? Data(contentsOf: self.fileURL), !data.isEmpty else { return [] } guard let text = String(data: data, encoding: .utf8) else { return [] } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 var decoded: [HistoricalUsageRecord] = [] decoded.reserveCapacity(text.count / 80) for rawLine in text.split(separator: "\n", omittingEmptySubsequences: true) { let line = String(rawLine).trimmingCharacters(in: .whitespacesAndNewlines) guard !line.isEmpty, let lineData = line.data(using: .utf8) else { continue } guard var record = try? decoder.decode(HistoricalUsageRecord.self, from: lineData) else { continue } record = HistoricalUsageRecord( v: record.v, provider: record.provider, windowKind: record.windowKind, source: record.source, accountKey: record.accountKey?.isEmpty == false ? record.accountKey : nil, sampledAt: record.sampledAt, usedPercent: Self.clamp(record.usedPercent, lower: 0, upper: 100), resetsAt: Self.normalizeReset(record.resetsAt), windowMinutes: record.windowMinutes) decoded.append(record) } return decoded } private func persist() { let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 encoder.outputFormatting = [.sortedKeys] var lines: [String] = [] lines.reserveCapacity(self.records.count) for record in self.records { guard let data = try? encoder.encode(record), let line = String(data: data, encoding: .utf8) else { continue } lines.append(line) } let payload = (lines.joined(separator: "\n") + "\n").data(using: .utf8) ?? Data() let directory = self.fileURL.deletingLastPathComponent() do { try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) try payload.write(to: self.fileURL, options: [.atomic]) } catch { // Best-effort cache file; ignore write failures. } } private func buildDataset(accountKey: String?) -> CodexHistoricalDataset? { let scoped = self.records.filter { record in guard Self.isCodexSecondaryRecord(record) else { return false } if let accountKey { return record.accountKey == accountKey } return record.accountKey == nil } return self.buildDataset(from: scoped) } private func buildDataset( canonicalAccountKey: String?, canonicalEmailHashKey: String?, legacyEmailHash: String?, hasAdjacentMultiAccountVeto: Bool) -> CodexHistoricalDataset? { guard let canonicalAccountKey else { return self.buildDataset(accountKey: nil) } let shouldIncludeUnscoped = CodexHistoryOwnership.hasStrictSingleAccountContinuity( scopedRawKeys: Self.scopedRawKeysRelevantToCodexUnscopedHistory(self.records), targetCanonicalKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey, legacyEmailHash: legacyEmailHash, hasAdjacentMultiAccountVeto: hasAdjacentMultiAccountVeto) let scoped = self.records.filter { record in guard Self.isCodexSecondaryRecord(record) else { return false } guard let rawKey = record.accountKey else { return shouldIncludeUnscoped } let owner = CodexHistoryOwnership.classifyPersistedKey(rawKey, legacyEmailHash: legacyEmailHash) return CodexHistoryOwnership.belongsToTargetContinuity( owner, targetCanonicalKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey) } return self.buildDataset(from: scoped) } private func buildDataset(from scoped: [HistoricalUsageRecord]) -> CodexHistoricalDataset? { struct WeekKey: Hashable { let resetsAt: Date let windowMinutes: Int } if scoped.isEmpty { return nil } let grouped = Dictionary(grouping: scoped) { WeekKey(resetsAt: $0.resetsAt, windowMinutes: $0.windowMinutes) } var weeks: [HistoricalWeekProfile] = [] weeks.reserveCapacity(grouped.count) for (key, samples) in grouped { let duration = TimeInterval(key.windowMinutes) * 60 guard duration > 0 else { continue } let windowStart = key.resetsAt.addingTimeInterval(-duration) guard Self.isCompleteWeek(samples: samples, windowStart: windowStart, resetsAt: key.resetsAt) else { continue } guard let curve = Self.reconstructWeekCurve( samples: samples, windowStart: windowStart, windowDuration: duration, gridPointCount: CodexHistoricalDataset.gridPointCount) else { continue } weeks.append(HistoricalWeekProfile( resetsAt: key.resetsAt, windowMinutes: key.windowMinutes, curve: curve)) } weeks.sort { $0.resetsAt < $1.resetsAt } if weeks.isEmpty { return nil } return CodexHistoricalDataset(weeks: weeks) } private nonisolated static func isCodexSecondaryRecord(_ record: HistoricalUsageRecord) -> Bool { record.provider == .codex && record.windowKind == .secondary && record.windowMinutes > 0 } private static func reconstructWeekCurve( samples: [HistoricalUsageRecord], windowStart: Date, windowDuration: TimeInterval, gridPointCount: Int) -> [Double]? { guard gridPointCount >= 2 else { return nil } var points = samples.map { sample -> (u: Double, value: Double) in let offset = sample.sampledAt.timeIntervalSince(windowStart) let u = Self.clamp(offset / windowDuration, lower: 0, upper: 1) return (u: u, value: Self.clamp(sample.usedPercent, lower: 0, upper: 100)) } points.sort { lhs, rhs in if lhs.u == rhs.u { return lhs.value < rhs.value } return lhs.u < rhs.u } guard !points.isEmpty else { return nil } // Enforce monotonicity on observed samples before interpolation. var monotonePoints: [(u: Double, value: Double)] = [] monotonePoints.reserveCapacity(points.count) var runningMax = 0.0 for point in points { runningMax = max(runningMax, point.value) monotonePoints.append((u: point.u, value: runningMax)) } // Anchor reconstructed curves to reset start and end-of-week plateau. let endValue = monotonePoints.last?.value ?? 0 monotonePoints.append((u: 0, value: 0)) monotonePoints.append((u: 1, value: endValue)) monotonePoints.sort { lhs, rhs in if lhs.u == rhs.u { return lhs.value < rhs.value } return lhs.u < rhs.u } runningMax = 0 for index in monotonePoints.indices { runningMax = max(runningMax, monotonePoints[index].value) monotonePoints[index].value = runningMax }Lines 1–500 of 975. Load more
import CodexBarCore import Foundation enum HistoricalUsageWindowKind: String, Codable { case secondary } enum HistoricalUsageRecordSource: String, Codable { case live case backfill } struct HistoricalUsageRecord: Codable { let v: Int let provider: UsageProvider let windowKind: HistoricalUsageWindowKind let source: HistoricalUsageRecordSource let accountKey: String? let sampledAt: Date let usedPercent: Double let resetsAt: Date let windowMinutes: Int init( v: Int, provider: UsageProvider, windowKind: HistoricalUsageWindowKind, source: HistoricalUsageRecordSource, accountKey: String?, sampledAt: Date, usedPercent: Double, resetsAt: Date, windowMinutes: Int) { self.v = v self.provider = provider self.windowKind = windowKind self.source = source self.accountKey = accountKey self.sampledAt = sampledAt self.usedPercent = usedPercent self.resetsAt = resetsAt self.windowMinutes = windowMinutes } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.v = try container.decodeIfPresent(Int.self, forKey: .v) ?? 1 self.provider = try container.decode(UsageProvider.self, forKey: .provider) self.windowKind = try container.decode(HistoricalUsageWindowKind.self, forKey: .windowKind) self.source = try container.decodeIfPresent(HistoricalUsageRecordSource.self, forKey: .source) ?? .live self.accountKey = try container.decodeIfPresent(String.self, forKey: .accountKey) self.sampledAt = try container.decode(Date.self, forKey: .sampledAt) self.usedPercent = try container.decode(Double.self, forKey: .usedPercent) self.resetsAt = try container.decode(Date.self, forKey: .resetsAt) self.windowMinutes = try container.decode(Int.self, forKey: .windowMinutes) } } struct HistoricalWeekProfile { let resetsAt: Date let windowMinutes: Int let curve: [Double] } struct CodexHistoricalDataset { static let gridPointCount = 169 let weeks: [HistoricalWeekProfile] } actor HistoricalUsageHistoryStore { private static let schemaVersion = 1 private static let writeInterval: TimeInterval = 30 * 60 private static let writeDeltaThreshold: Double = 1 private static let retentionDays: TimeInterval = 56 * 24 * 60 * 60 private static let minimumWeekSamples = 6 private static let boundaryCoverageWindow: TimeInterval = 24 * 60 * 60 private static let backfillWindowCapWeeks = 8 private static let backfillCalibrationMinimumUsedPercent = 1.0 private static let backfillCalibrationMinimumCredits = 0.001 private static let backfillSampleFractions: [Double] = (0...14).map { Double($0) / 14.0 } private static let coverageTolerance: TimeInterval = 16 * 60 * 60 private static let resetBucketSeconds: TimeInterval = 5 * 60 private let fileURL: URL private var records: [HistoricalUsageRecord] = [] private var loaded = false init(fileURL: URL? = nil) { self.fileURL = fileURL ?? HistoricalUsageHistoryStore.defaultFileURL() } func loadCodexDataset(accountKey: String?) -> CodexHistoricalDataset? { self.ensureLoaded() return self.buildDataset(accountKey: accountKey) } func loadCodexDataset( canonicalAccountKey: String?, canonicalEmailHashKey: String?, legacyEmailHash: String?, hasAdjacentMultiAccountVeto: Bool) -> CodexHistoricalDataset? { self.ensureLoaded() return self.buildDataset( canonicalAccountKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey, legacyEmailHash: legacyEmailHash, hasAdjacentMultiAccountVeto: hasAdjacentMultiAccountVeto) } func recordCodexWeekly( window: RateWindow, sampledAt: Date = .init(), accountKey: String?) -> CodexHistoricalDataset? { guard let rawResetsAt = window.resetsAt else { return self.loadCodexDataset(accountKey: accountKey) } guard let windowMinutes = window.windowMinutes, windowMinutes > 0 else { return self.loadCodexDataset(accountKey: accountKey) } self.ensureLoaded() let resetsAt = Self.normalizeReset(rawResetsAt) let sample = HistoricalUsageRecord( v: Self.schemaVersion, provider: .codex, windowKind: .secondary, source: .live, accountKey: accountKey, sampledAt: sampledAt, usedPercent: Self.clamp(window.usedPercent, lower: 0, upper: 100), resetsAt: resetsAt, windowMinutes: windowMinutes) if !self.shouldAccept(sample) { return self.buildDataset(accountKey: accountKey) } self.records.append(sample) self.pruneOldRecords(now: sampledAt) self.records.sort { lhs, rhs in if lhs.sampledAt == rhs.sampledAt { if lhs.resetsAt == rhs.resetsAt { return lhs.usedPercent < rhs.usedPercent } return lhs.resetsAt < rhs.resetsAt } return lhs.sampledAt < rhs.sampledAt } self.persist() return self.buildDataset(accountKey: accountKey) } func backfillCodexWeeklyFromUsageBreakdown( _ breakdown: [OpenAIDashboardDailyBreakdown], referenceWindow: RateWindow, now: Date = .init(), accountKey: String?) -> CodexHistoricalDataset? { self.ensureLoaded() let existingDataset = self.buildDataset(accountKey: accountKey) guard let rawResetsAt = referenceWindow.resetsAt else { return existingDataset } guard let windowMinutes = referenceWindow.windowMinutes, windowMinutes > 0 else { return existingDataset } let resetsAt = Self.normalizeReset(rawResetsAt) let duration = TimeInterval(windowMinutes) * 60 guard duration > 0 else { return existingDataset } let windowStart = resetsAt.addingTimeInterval(-duration) let calibrationEnd = Self.clampDate(now, lower: windowStart, upper: resetsAt) let dayUsages = Self.parseDayUsages( from: breakdown, asOf: calibrationEnd, fillingFrom: windowStart) guard !dayUsages.isEmpty else { return existingDataset } guard let coverageStart = dayUsages.first?.start, let coverageEnd = dayUsages.last?.end else { return existingDataset } guard coverageStart <= windowStart.addingTimeInterval(Self.coverageTolerance) else { return existingDataset } guard coverageEnd >= calibrationEnd.addingTimeInterval(-Self.coverageTolerance) else { return existingDataset } let currentUsedPercent = Self.clamp(referenceWindow.usedPercent, lower: 0, upper: 100) guard currentUsedPercent >= Self.backfillCalibrationMinimumUsedPercent else { return existingDataset } let currentCredits = Self.creditsUsed( from: dayUsages, between: windowStart, and: calibrationEnd) guard currentCredits > Self.backfillCalibrationMinimumCredits else { return existingDataset } let estimatedCreditsAtLimit = currentCredits / (currentUsedPercent / 100) guard estimatedCreditsAtLimit.isFinite, estimatedCreditsAtLimit > Self.backfillCalibrationMinimumCredits else { return existingDataset } struct RecordKey: Hashable { let resetsAt: Date let sampledAt: Date let windowMinutes: Int let accountKey: String? } var synthesized: [HistoricalUsageRecord] = [] synthesized.reserveCapacity(Self.backfillWindowCapWeeks * Self.backfillSampleFractions.count) for weeksBack in 1...Self.backfillWindowCapWeeks { let reset = Self.normalizeReset(resetsAt.addingTimeInterval(-duration * Double(weeksBack))) let start = reset.addingTimeInterval(-duration) guard start >= coverageStart.addingTimeInterval(-Self.coverageTolerance), reset <= coverageEnd.addingTimeInterval(Self.coverageTolerance) else { continue } let existingForWeek = self.records.filter { $0.provider == .codex && $0.windowKind == .secondary && $0.windowMinutes == windowMinutes && $0.accountKey == accountKey && $0.resetsAt == reset } if Self.isCompleteWeek(samples: existingForWeek, windowStart: start, resetsAt: reset) { continue } var existingRecordKeys = Set(existingForWeek.map { RecordKey( resetsAt: $0.resetsAt, sampledAt: $0.sampledAt, windowMinutes: $0.windowMinutes, accountKey: $0.accountKey) }) let weekCredits = Self.creditsUsed(from: dayUsages, between: start, and: reset) guard weekCredits > Self.backfillCalibrationMinimumCredits else { continue } for fraction in Self.backfillSampleFractions { let sampledAt = start.addingTimeInterval(duration * fraction) let recordKey = RecordKey( resetsAt: reset, sampledAt: sampledAt, windowMinutes: windowMinutes, accountKey: accountKey) guard !existingRecordKeys.contains(recordKey) else { continue } let cumulativeCredits = Self.creditsUsed(from: dayUsages, between: start, and: sampledAt) let usedPercent = Self.clamp((cumulativeCredits / estimatedCreditsAtLimit) * 100, lower: 0, upper: 100) synthesized.append(HistoricalUsageRecord( v: Self.schemaVersion, provider: .codex, windowKind: .secondary, source: .backfill, accountKey: accountKey, sampledAt: sampledAt, usedPercent: usedPercent, resetsAt: reset, windowMinutes: windowMinutes)) existingRecordKeys.insert(recordKey) } } guard !synthesized.isEmpty else { return existingDataset } self.records.append(contentsOf: synthesized) self.pruneOldRecords(now: now) self.records.sort { lhs, rhs in if lhs.sampledAt == rhs.sampledAt { if lhs.resetsAt == rhs.resetsAt { return lhs.usedPercent < rhs.usedPercent } return lhs.resetsAt < rhs.resetsAt } return lhs.sampledAt < rhs.sampledAt } self.persist() return self.buildDataset(accountKey: accountKey) } private func shouldAccept(_ sample: HistoricalUsageRecord) -> Bool { guard let prior = self.records .last(where: { $0.provider == sample.provider && $0.windowKind == sample.windowKind && $0.accountKey == sample.accountKey && $0.windowMinutes == sample.windowMinutes }) else { return true } if prior.resetsAt != sample.resetsAt { return true } if sample.sampledAt.timeIntervalSince(prior.sampledAt) >= Self.writeInterval { return true } if abs(sample.usedPercent - prior.usedPercent) >= Self.writeDeltaThreshold { return true } return false } private func pruneOldRecords(now: Date) { let cutoff = now.addingTimeInterval(-Self.retentionDays) self.records.removeAll { $0.sampledAt < cutoff } } private func ensureLoaded() { guard !self.loaded else { return } self.loaded = true self.records = self.readRecordsFromDisk() self.pruneOldRecords(now: .init()) } private func readRecordsFromDisk() -> [HistoricalUsageRecord] { guard let data = try? Data(contentsOf: self.fileURL), !data.isEmpty else { return [] } guard let text = String(data: data, encoding: .utf8) else { return [] } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 var decoded: [HistoricalUsageRecord] = [] decoded.reserveCapacity(text.count / 80) for rawLine in text.split(separator: "\n", omittingEmptySubsequences: true) { let line = String(rawLine).trimmingCharacters(in: .whitespacesAndNewlines) guard !line.isEmpty, let lineData = line.data(using: .utf8) else { continue } guard var record = try? decoder.decode(HistoricalUsageRecord.self, from: lineData) else { continue } record = HistoricalUsageRecord( v: record.v, provider: record.provider, windowKind: record.windowKind, source: record.source, accountKey: record.accountKey?.isEmpty == false ? record.accountKey : nil, sampledAt: record.sampledAt, usedPercent: Self.clamp(record.usedPercent, lower: 0, upper: 100), resetsAt: Self.normalizeReset(record.resetsAt), windowMinutes: record.windowMinutes) decoded.append(record) } return decoded } private func persist() { let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 encoder.outputFormatting = [.sortedKeys] var lines: [String] = [] lines.reserveCapacity(self.records.count) for record in self.records { guard let data = try? encoder.encode(record), let line = String(data: data, encoding: .utf8) else { continue } lines.append(line) } let payload = (lines.joined(separator: "\n") + "\n").data(using: .utf8) ?? Data() let directory = self.fileURL.deletingLastPathComponent() do { try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true) try payload.write(to: self.fileURL, options: [.atomic]) } catch { // Best-effort cache file; ignore write failures. } } private func buildDataset(accountKey: String?) -> CodexHistoricalDataset? { let scoped = self.records.filter { record in guard Self.isCodexSecondaryRecord(record) else { return false } if let accountKey { return record.accountKey == accountKey } return record.accountKey == nil } return self.buildDataset(from: scoped) } private func buildDataset( canonicalAccountKey: String?, canonicalEmailHashKey: String?, legacyEmailHash: String?, hasAdjacentMultiAccountVeto: Bool) -> CodexHistoricalDataset? { guard let canonicalAccountKey else { return self.buildDataset(accountKey: nil) } let shouldIncludeUnscoped = CodexHistoryOwnership.hasStrictSingleAccountContinuity( scopedRawKeys: Self.scopedRawKeysRelevantToCodexUnscopedHistory(self.records), targetCanonicalKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey, legacyEmailHash: legacyEmailHash, hasAdjacentMultiAccountVeto: hasAdjacentMultiAccountVeto) let scoped = self.records.filter { record in guard Self.isCodexSecondaryRecord(record) else { return false } guard let rawKey = record.accountKey else { return shouldIncludeUnscoped } let owner = CodexHistoryOwnership.classifyPersistedKey(rawKey, legacyEmailHash: legacyEmailHash) return CodexHistoryOwnership.belongsToTargetContinuity( owner, targetCanonicalKey: canonicalAccountKey, canonicalEmailHashKey: canonicalEmailHashKey) } return self.buildDataset(from: scoped) } private func buildDataset(from scoped: [HistoricalUsageRecord]) -> CodexHistoricalDataset? { struct WeekKey: Hashable { let resetsAt: Date let windowMinutes: Int } if scoped.isEmpty { return nil } let grouped = Dictionary(grouping: scoped) { WeekKey(resetsAt: $0.resetsAt, windowMinutes: $0.windowMinutes) } var weeks: [HistoricalWeekProfile] = [] weeks.reserveCapacity(grouped.count) for (key, samples) in grouped { let duration = TimeInterval(key.windowMinutes) * 60 guard duration > 0 else { continue } let windowStart = key.resetsAt.addingTimeInterval(-duration) guard Self.isCompleteWeek(samples: samples, windowStart: windowStart, resetsAt: key.resetsAt) else { continue } guard let curve = Self.reconstructWeekCurve( samples: samples, windowStart: windowStart, windowDuration: duration, gridPointCount: CodexHistoricalDataset.gridPointCount) else { continue } weeks.append(HistoricalWeekProfile( resetsAt: key.resetsAt, windowMinutes: key.windowMinutes, curve: curve)) } weeks.sort { $0.resetsAt < $1.resetsAt } if weeks.isEmpty { return nil } return CodexHistoricalDataset(weeks: weeks) } private nonisolated static func isCodexSecondaryRecord(_ record: HistoricalUsageRecord) -> Bool { record.provider == .codex && record.windowKind == .secondary && record.windowMinutes > 0 } private static func reconstructWeekCurve( samples: [HistoricalUsageRecord], windowStart: Date, windowDuration: TimeInterval, gridPointCount: Int) -> [Double]? { guard gridPointCount >= 2 else { return nil } var points = samples.map { sample -> (u: Double, value: Double) in let offset = sample.sampledAt.timeIntervalSince(windowStart) let u = Self.clamp(offset / windowDuration, lower: 0, upper: 1) return (u: u, value: Self.clamp(sample.usedPercent, lower: 0, upper: 100)) } points.sort { lhs, rhs in if lhs.u == rhs.u { return lhs.value < rhs.value } return lhs.u < rhs.u } guard !points.isEmpty else { return nil } // Enforce monotonicity on observed samples before interpolation. var monotonePoints: [(u: Double, value: Double)] = [] monotonePoints.reserveCapacity(points.count) var runningMax = 0.0 for point in points { runningMax = max(runningMax, point.value) monotonePoints.append((u: point.u, value: runningMax)) } // Anchor reconstructed curves to reset start and end-of-week plateau. let endValue = monotonePoints.last?.value ?? 0 monotonePoints.append((u: 0, value: 0)) monotonePoints.append((u: 1, value: endValue)) monotonePoints.sort { lhs, rhs in if lhs.u == rhs.u { return lhs.value < rhs.value } return lhs.u < rhs.u } runningMax = 0 for index in monotonePoints.indices { runningMax = max(runningMax, monotonePoints[index].value) monotonePoints[index].value = runningMax }