Skip to content

Commit 166d5e0

Browse files
fix: preserve Codex spend window under byte pressure
Co-authored-by: Whiteknight07 <fiestyboxer@gmail.com>
1 parent 17afef7 commit 166d5e0

3 files changed

Lines changed: 74 additions & 106 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
## 0.49.2 — Unreleased
44

5+
### Fixed
6+
- Codex: preserve requested Spend Dashboard history when the local cost cache exceeds its byte budget, rather than deleting in-window sessions or repeatedly rebuilding protected data (#2823). Thanks @WillStark for the report and @Whiteknight07 for the initial fix!
7+
- Codex: avoid repeatedly converting historical token snapshots during cost-cache refreshes, preventing sustained CPU usage on large session histories.
8+
59
## 0.49.1 — 2026-08-09
610

711
### Fixed
8-
- Codex: avoid repeatedly converting historical token snapshots during cost-cache refreshes, preventing sustained CPU usage on large session histories.
912
- DeepInfra: show billing-cycle spend against a positive spending limit in the automatic menu-bar icon (#2822). Thanks @selfagency for the report!
1013
- z.ai: restore pace for verified 5-hour, weekly, and MCP-monthly usage windows without treating rolling 30-day limits as calendar months (#2431). Thanks @kiranmagic7!
1114
- Codex: publish refreshed core quota immediately while optional Credits and OpenAI Web enrichment continues, without unfreezing cards whose layout still needs reconciliation (#2799). Thanks @Yuxin-Qiao!

Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore+Retention.swift

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,9 @@ extension CostUsageStore {
283283
}
284284

285285
var catchUpRequired = false
286-
// The row budget mirrors the former entry budget: it only ever removes files the
287-
// requested window does not read. In-window and recently active files are never
288-
// dropped just for a row overage; the byte budget below is the sole authority
289-
// that may sacrifice in-window data.
286+
// The row and byte budgets only remove files outside the requested window. Once
287+
// only protected data remains, preserving report fidelity takes precedence over
288+
// forcing the database under its best-effort byte cap.
290289
while try Self.rowCount(database) > Int64(rowLimit) {
291290
guard try Self.deleteOldestRetainedFile(
292291
database,
@@ -305,15 +304,8 @@ extension CostUsageStore {
305304
sinceDay: sinceDay,
306305
untilDay: untilDay,
307306
calendar: calendar,
308-
protectRequestedWindow: false)
309-
else {
310-
guard try Self.stripOldestRebuildableDetail(database) else { break }
311-
catchUpRequired = true
312-
try Self.markCatchUpRequired(database)
313-
try Self.reclaimFreePages(database)
314-
fileBytes = Self.fileSize(at: self.databaseURL)
315-
continue
316-
}
307+
protectRequestedWindow: true)
308+
else { break }
317309
catchUpRequired = true
318310
try Self.reclaimFreePages(database)
319311
fileBytes = Self.fileSize(at: self.databaseURL)
@@ -393,43 +385,6 @@ extension CostUsageStore {
393385
try self.scalarInt(database, "SELECT COUNT(*) FROM files")
394386
}
395387

396-
private static func stripOldestRebuildableDetail(_ database: OpaquePointer) throws -> Bool {
397-
let statement = try self.prepare(database, """
398-
SELECT f.id, f.scan_state
399-
FROM files f
400-
WHERE NOT EXISTS (SELECT 1 FROM buffered_lines b WHERE b.file_id = f.id)
401-
AND ((SELECT COUNT(*) FROM token_snapshots t WHERE t.file_id = f.id) > 0
402-
OR (SELECT COUNT(*) FROM usage_rows r WHERE r.file_id = f.id) > 0)
403-
ORDER BY f.updated_at_ms, f.id
404-
LIMIT 1
405-
""")
406-
defer { sqlite3_finalize(statement) }
407-
guard sqlite3_step(statement) == SQLITE_ROW,
408-
let stateData = self.columnData(statement, at: 1),
409-
var state = try? JSONDecoder().decode(CostUsageStoreScanState.self, from: stateData)
410-
else { return false }
411-
let fileID = sqlite3_column_int64(statement, 0)
412-
state.isComplete = false
413-
state.resumePayload = nil
414-
state.tokenTimestampsMonotonic = nil
415-
state.nextUsageRowIndex = nil
416-
let updatedState = try JSONEncoder().encode(state)
417-
let update = try self.prepare(database, """
418-
UPDATE files
419-
SET parsed_bytes = 0, anchor_indexed_bytes = NULL, anchor_window_start = NULL,
420-
anchor_sha256 = NULL, scan_state = ?, scan_complete = 0
421-
WHERE id = ?
422-
""")
423-
defer { sqlite3_finalize(update) }
424-
self.bind(updatedState, to: update, at: 1)
425-
sqlite3_bind_int64(update, 2, fileID)
426-
try self.stepDone(update, database: database)
427-
try self.execute(database, "DELETE FROM token_snapshots WHERE file_id = \(fileID)")
428-
try self.execute(database, "DELETE FROM usage_rows WHERE file_id = \(fileID)")
429-
try self.execute(database, "DELETE FROM accumulators WHERE file_id = \(fileID)")
430-
return true
431-
}
432-
433388
private static func rebuildDayAggregates(_ database: OpaquePointer) throws {
434389
try self.execute(database, "DELETE FROM day_aggregates")
435390
try self.execute(database, """

Tests/CodexBarTests/CostUsageStoreTests.swift

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ extension CostUsageStoreTests {
983983

984984
extension CostUsageStoreTests {
985985
@Test
986-
func `save preserves an existing complete previous report across repeated trims`() async throws {
986+
func `save preserves an existing previous report when protected data exceeds the byte cap`() async throws {
987987
let fixture = try StoreFixture()
988988
defer { fixture.remove() }
989989
let store = CostUsageStore(cacheRoot: fixture.root)
@@ -1030,7 +1030,7 @@ extension CostUsageStoreTests {
10301030
reportWindow: (sinceKey: "2026-06-01", untilKey: "2026-07-01"),
10311031
fileBudgetBytes: 1)
10321032

1033-
#expect(result.catchUpRequired)
1033+
#expect(result.catchUpRequired == false)
10341034
let metadata = await store.fetchMetadata()
10351035
let payload = try #require(metadata.previousReportPayload)
10361036
let preserved = try JSONDecoder().decode(CostUsageCodexPreviousReport.self, from: payload)
@@ -1040,7 +1040,7 @@ extension CostUsageStoreTests {
10401040
}
10411041

10421042
@Test
1043-
func `save catch up report honors a non-gregorian system calendar`() async throws {
1043+
func `save over byte cap keeps non-gregorian in window report intact`() async throws {
10441044
let fixture = try StoreFixture()
10451045
defer { fixture.remove() }
10461046
let store = CostUsageStore(cacheRoot: fixture.root)
@@ -1063,13 +1063,12 @@ extension CostUsageStoreTests {
10631063
requestedScanWindow: (sinceKey: "2026-06-01", untilKey: "2026-07-01"),
10641064
reportWindow: (sinceKey: "2026-06-01", untilKey: "2026-07-01"),
10651065
fileBudgetBytes: 1)
1066+
let report = await store.readReport(sinceDay: "2026-06-01", untilDay: "2026-07-01")
10661067

1067-
#expect(result.catchUpRequired)
1068-
let metadata = await store.fetchMetadata()
1069-
let payload = try #require(metadata.previousReportPayload)
1070-
let previous = try JSONDecoder().decode(CostUsageCodexPreviousReport.self, from: payload)
1071-
#expect(previous.data.contains { $0.date == "2026-06-05" })
1072-
#expect(previous.data.contains { $0.date == "1483-06-05" } == false)
1068+
#expect(result.catchUpRequired == false)
1069+
#expect(await store.fetchMetadata().previousReportPayload == nil)
1070+
#expect(report.aggregates.map(\.day) == ["2026-06-05"])
1071+
#expect(report.aggregates.contains { $0.day == "1483-06-05" } == false)
10731072
}
10741073
}
10751074

@@ -1174,35 +1173,49 @@ extension CostUsageStoreTests {
11741173
}
11751174

11761175
@Test
1177-
func `in window byte budget trim marks catch up and preserves previous report`() async throws {
1176+
func `byte budget preserves in window data across repeated enforcement`() async throws {
11781177
let fixture = try StoreFixture()
11791178
defer { fixture.remove() }
11801179
let store = CostUsageStore(cacheRoot: fixture.root)
1181-
let previous = Data("previous-report".utf8)
1182-
var metadata = CostUsageStoreMetadata.empty
1183-
metadata.lastScanUnixMs = 1234
1184-
metadata.previousReportPayload = previous
1185-
#expect(await store.setMetadata(metadata))
1180+
let day = "2026-08-01"
1181+
let model = "gpt-5.5"
11861182
for (index, path) in ["/rollouts/one.jsonl", "/rollouts/two.jsonl"].enumerated() {
1187-
#expect(await store.upsertFile(Self.file(path: path, day: "2026-08-01", updatedAt: Int64(index))))
1188-
let row = CostUsageStoreUsageRow(
1183+
let file = Self.file(path: path, day: day, updatedAt: Int64(index))
1184+
#expect(await store.upsertFile(file))
1185+
#expect(await store.replaceUsageRows(path: path, rows: [CostUsageStoreUsageRow(
11891186
path: path,
11901187
rowIndex: 0,
1191-
payload: Data(repeating: UInt8(index), count: 256 * 1024))
1192-
#expect(await store.replaceUsageRows(path: path, rows: [row]))
1188+
payload: Data(repeating: UInt8(index), count: 256 * 1024))]))
1189+
#expect(await store.replaceFileDayAggregates(
1190+
path: path,
1191+
aggregates: [Self.aggregate(day: day, model: model, scale: 1)]))
11931192
}
1193+
#expect(await store.mergeDayAggregates([Self.aggregate(day: day, model: model, scale: 2)]))
11941194

1195-
let result = await store.enforceBudgets(
1195+
let first = await store.enforceBudgets(
11961196
maxRows: .max,
11971197
maxFileBytes: 1,
1198-
requestedSinceDay: "2026-08-01",
1199-
requestedUntilDay: "2026-08-02")
1200-
let retained = await store.fetchMetadata()
1201-
1202-
#expect(result.catchUpRequired)
1203-
#expect(retained.catchUpPending)
1204-
#expect(retained.lastScanUnixMs == 0)
1205-
#expect(retained.previousReportPayload == previous)
1198+
requestedSinceDay: day,
1199+
requestedUntilDay: day)
1200+
let second = await store.enforceBudgets(
1201+
maxRows: .max,
1202+
maxFileBytes: 1,
1203+
requestedSinceDay: day,
1204+
requestedUntilDay: day)
1205+
let report = await store.readReport(sinceDay: day, untilDay: day)
1206+
1207+
#expect(first.catchUpRequired == false)
1208+
#expect(second.catchUpRequired == false)
1209+
#expect(first.deletedRows == 0)
1210+
#expect(second.deletedRows == 0)
1211+
#expect(first.rowCount == 2)
1212+
#expect(second.rowCount == 2)
1213+
#expect(first.fileBytes > 1)
1214+
#expect(second.fileBytes > 1)
1215+
#expect(await store.fetchUsageRows(path: "/rollouts/one.jsonl").count == 1)
1216+
#expect(await store.fetchUsageRows(path: "/rollouts/two.jsonl").count == 1)
1217+
#expect(report.aggregates == [Self.aggregate(day: day, model: model, scale: 2)])
1218+
#expect(await store.fetchMetadata().catchUpPending == false)
12061219
}
12071220

12081221
@Test
@@ -1230,39 +1243,37 @@ extension CostUsageStoreTests {
12301243
}
12311244

12321245
@Test
1233-
func `byte budget strips detail from a protected file instead of stalling`() async throws {
1246+
func `byte budget removes only data outside the requested window`() async throws {
12341247
let fixture = try StoreFixture()
12351248
defer { fixture.remove() }
12361249
let store = CostUsageStore(cacheRoot: fixture.root)
1237-
var file = Self.file(path: "/rollouts/resuming.jsonl", day: "2026-08-01")
1238-
file.scanState.isComplete = false
1239-
#expect(await store.upsertFile(file))
1240-
#expect(await store.appendTokenSnapshots([Self.snapshot(path: file.path, eventIndex: 0)]))
1241-
#expect(await store.replaceUsageRows(path: file.path, rows: [CostUsageStoreUsageRow(
1242-
path: file.path,
1243-
rowIndex: 0,
1244-
payload: Data(repeating: 7, count: 256 * 1024))]))
1245-
#expect(await store.upsertAccumulator(Self.accumulator(path: file.path)))
1250+
let stale = Self.file(path: "/rollouts/stale.jsonl", day: "2026-06-01", updatedAt: 0)
1251+
let current = Self.file(path: "/rollouts/current.jsonl", day: "2026-08-01", updatedAt: 1)
1252+
for file in [stale, current] {
1253+
#expect(await store.upsertFile(file))
1254+
#expect(await store.replaceUsageRows(path: file.path, rows: [CostUsageStoreUsageRow(
1255+
path: file.path,
1256+
rowIndex: 0,
1257+
payload: Data(repeating: 7, count: 256 * 1024))]))
1258+
}
12461259

12471260
let result = await store.enforceBudgets(
12481261
maxRows: .max,
12491262
maxFileBytes: 1,
12501263
requestedSinceDay: "2026-08-01",
12511264
requestedUntilDay: "2026-08-02")
12521265

1253-
let stripped = try #require(await store.fetchFile(path: file.path))
1254-
#expect(result.catchUpRequired)
1255-
#expect(stripped.parsedBytes == 0)
1256-
#expect(stripped.scanState.isComplete == false)
1257-
#expect(stripped.scanState.resumePayload == nil)
1258-
#expect(await store.fetchTokenSnapshots(path: file.path).isEmpty)
1259-
#expect(await store.fetchUsageRows(path: file.path).isEmpty)
1260-
#expect(await store.fetchAccumulator(path: file.path) == nil)
1261-
#expect(await store.fetchMetadata().catchUpPending)
1266+
#expect(result.deletedRows == 1)
1267+
#expect(result.rowCount == 1)
1268+
#expect(result.fileBytes > 1)
1269+
#expect(await store.fetchFile(path: stale.path) == nil)
1270+
#expect(await store.fetchFile(path: current.path) != nil)
1271+
#expect(await store.fetchUsageRows(path: current.path).count == 1)
1272+
#expect(await store.fetchMetadata().catchUpPending == false)
12621273
}
12631274

12641275
@Test
1265-
func `byte budget compacts a fork parent required by a surviving child`() async throws {
1276+
func `byte budget preserves fork parent detail required by a surviving child`() async throws {
12661277
let fixture = try StoreFixture()
12671278
defer { fixture.remove() }
12681279
let store = CostUsageStore(cacheRoot: fixture.root)
@@ -1295,14 +1306,13 @@ extension CostUsageStoreTests {
12951306
requestedSinceDay: "2026-08-01",
12961307
requestedUntilDay: "2026-08-02")
12971308

1298-
// The parent cannot be deleted while the incomplete child still needs its baseline,
1299-
// so byte pressure compacts its rebuildable detail instead.
1300-
let compacted = try #require(await store.fetchFile(path: parent.path))
1301-
#expect(result.catchUpRequired)
1302-
#expect(compacted.parsedBytes == 0)
1303-
#expect(compacted.scanState.isComplete == false)
1304-
#expect(await store.fetchUsageRows(path: parent.path).isEmpty)
1309+
let retained = try #require(await store.fetchFile(path: parent.path))
1310+
#expect(result.catchUpRequired == false)
1311+
#expect(retained.parsedBytes == parent.parsedBytes)
1312+
#expect(retained.scanState.isComplete)
1313+
#expect(await store.fetchUsageRows(path: parent.path).count == 1)
13051314
#expect(await store.fetchFile(path: child.path) != nil)
1315+
#expect(await store.fetchMetadata().catchUpPending == false)
13061316
}
13071317

13081318
@Test

0 commit comments

Comments
 (0)